Commit 8d3592a9 by Christophe Geuzaine

- Save orientation of entities in MSH3 $Entities field

- new "-save_topology" option to save the $Entities section in MSH2 files
parent a18f6f6f
Pipeline #69 passed with stage
in 20 minutes 7 seconds
......@@ -84,8 +84,9 @@ std::vector<std::pair<std::string, std::string> > GetUsage()
s.push_back(mp("-part int", "Partition after batch mesh generation"));
s.push_back(mp("-partWeight tri|quad|tet|prism|hex int", "Weight of a triangle/quad/etc. "
"during partitioning"));
s.push_back(mp("-saveall", "Save all elements (discard physical group definitions)"));
s.push_back(mp("-parametric", "Save vertices with their parametric coordinates"));
s.push_back(mp("-save_all", "Save all elements (discard physical group definitions)"));
s.push_back(mp("-save_parametric", "Save vertices with their parametric coordinates"));
s.push_back(mp("-save_topology", "Save model topology"));
s.push_back(mp("-algo string", "Select mesh algorithm (meshadapt, del2d, front2d, "
"delquad, del3d, front3d, mmg3d, pack)"));
s.push_back(mp("-smooth int", "Set number of mesh smoothing steps"));
......@@ -839,10 +840,16 @@ void GetOptions(int argc, char *argv[])
i++;
CTX::instance()->mesh.binary = 1;
}
else if(!strcmp(argv[i] + 1, "parametric")) {
else if(!strcmp(argv[i] + 1, "save_parametric") ||
!strcmp(argv[i] + 1, "parametric")) {
i++;
CTX::instance()->mesh.saveParametric = 1;
}
else if(!strcmp(argv[i] + 1, "save_topology") ||
!strcmp(argv[i] + 1, "save_entities")) {
i++;
CTX::instance()->mesh.saveTopology = 1;
}
else if(!strcmp(argv[i] + 1, "algo")) {
i++;
if(argv[i]) {
......
......@@ -49,7 +49,8 @@ struct contextMeshOptions {
int minCircPoints, minCurvPoints;
int hoOptimize, hoNLayers, hoOptPrimSurfMesh;
double hoThresholdMin, hoThresholdMax, hoPoissonRatio;
int saveAll, saveTri, saveGroupsOfNodes, binary, bdfFieldFormat, saveParametric;
int saveAll, saveTri, saveGroupsOfNodes, binary, bdfFieldFormat;
int saveParametric, saveTopology;
int smoothNormals, zoneDefinition, clip;
int saveElementTagType;
int switchElementTags;
......
......@@ -1240,6 +1240,8 @@ StringXNumber MeshOptions_Number[] = {
{ F|O, "SaveElementTagType" , opt_mesh_save_element_tag_type , 1. ,
"Type of the element tag saved in mesh formats that don't support saving "
"physical or partition ids (1=elementary, 2=physical, 3=partition)" },
{ F|O, "SaveTopology" , opt_mesh_save_topology, 0. ,
"Save model topology in MSH2 output files (this is always saved in MSH3)" },
{ F|O, "SaveParametric" , opt_mesh_save_parametric , 0. ,
"Save parametric coordinates of nodes" },
{ F|O, "SaveGroupsOfNodes" , opt_mesh_save_groups_of_nodes , 0. ,
......
......@@ -6203,6 +6203,13 @@ double opt_mesh_save_parametric(OPT_ARGS_NUM)
return CTX::instance()->mesh.saveParametric;
}
double opt_mesh_save_topology(OPT_ARGS_NUM)
{
if(action & GMSH_SET)
CTX::instance()->mesh.saveTopology = val ? 1 : 0;
return CTX::instance()->mesh.saveTopology;
}
double opt_mesh_save_groups_of_nodes(OPT_ARGS_NUM)
{
if(action & GMSH_SET)
......
......@@ -508,6 +508,7 @@ double opt_mesh_draw_skin_only(OPT_ARGS_NUM);
double opt_mesh_save_all(OPT_ARGS_NUM);
double opt_mesh_save_element_tag_type(OPT_ARGS_NUM);
double opt_mesh_save_parametric(OPT_ARGS_NUM);
double opt_mesh_save_topology(OPT_ARGS_NUM);
double opt_mesh_save_groups_of_nodes(OPT_ARGS_NUM);
double opt_mesh_color_carousel(OPT_ARGS_NUM);
double opt_mesh_switch_elem_tags(OPT_ARGS_NUM);
......
......@@ -1392,7 +1392,7 @@ bool GFace::fillPointCloud(double maxDist,
#if defined(HAVE_MESH)
static void meshCompound (GFace* gf, bool verbose)
static void meshCompound(GFace* gf, bool verbose)
{
discreteFace *df = new discreteFace (gf->model(), gf->tag() + 100000);
......@@ -1415,7 +1415,7 @@ static void meshCompound (GFace* gf, bool verbose)
}
std::vector<int> cedges;
cedges.insert(cedges.begin(), ec.begin(), ec.end());
df->setBoundEdges(gf->model(), cedges);
df->setBoundEdges(cedges);
df->createGeometry();
df->mesh(verbose);
delete df;
......
......@@ -2837,7 +2837,7 @@ void GModel::createTopologyFromFaces(std::vector<discreteFace*> &discFaces, int
std::map<int, std::vector<int> >::iterator ite = face2Edges.find((*it)->tag());
if (ite != face2Edges.end()){
std::vector<int> bcEdges = ite->second;
(*it)->setBoundEdges(this, bcEdges);
(*it)->setBoundEdges(bcEdges);
}
}
......@@ -4023,7 +4023,7 @@ void GModel::classifyFaces(std::set<GFace*> &_faces)
std::map<discreteFace*,std::vector<int> >::iterator itFT = newFaceTopology.begin();
for (;itFT != newFaceTopology.end();++itFT){
itFT->first->setBoundEdges(this, itFT->second);
itFT->first->setBoundEdges(itFT->second);
}
for (std::map<std::pair<int, int>, GEdge*>::iterator it = newEdges.begin();
......
......@@ -75,13 +75,15 @@ static void readMSHEntities(FILE *fp, GModel *gm)
GFace *gf = gm->getFaceByTag(tag);
if (!gf){
discreteFace *df = new discreteFace(gm, tag);
std::vector<int> edges;
std::vector<int> edges, signs;
for (int j = 0; j < n; j++){
int tage;
if(fscanf(fp, "%d", &tage) != 1) return;
edges.push_back(tage);
edges.push_back(std::abs(tage));
int sign = tage > 0 ? 1 : -1;
signs.push_back(sign);
}
df->setBoundEdges(gm, edges);
df->setBoundEdges(edges, signs);
gm->add(df);
gf = df;
}
......@@ -93,13 +95,15 @@ static void readMSHEntities(FILE *fp, GModel *gm)
GRegion *gr = gm->getRegionByTag(tag);
if (!gr){
discreteRegion *dr = new discreteRegion(gm, tag);
std::set<int> faces;
std::vector<int> faces, signs;
for (int j = 0; j < n; j++){
int tagf;
if(fscanf(fp, "%d", &tagf) != 1) return;
faces.insert(tagf);
faces.push_back(tagf);
int sign = tagf > 0 ? 1 : -1;
signs.push_back(sign);
}
dr->setBoundFaces(faces);
dr->setBoundFaces(faces, signs);
gm->add(dr);
gr = dr;
}
......@@ -482,7 +486,7 @@ static void writeMSHPhysicals(FILE *fp, GEntity *ge)
fprintf(fp, "%d ", *itp);
}
static void writeMSHEntities(FILE *fp, GModel *gm)
void writeMSHEntities(FILE *fp, GModel *gm)
{
fprintf(fp, "$Entities\n");
fprintf (fp, "%d %d %d %d\n", gm->getNumVertices(), gm->getNumEdges(),
......@@ -505,19 +509,37 @@ static void writeMSHEntities(FILE *fp, GModel *gm)
}
for (GModel::fiter it = gm->firstFace(); it != gm->lastFace(); ++it) {
std::list<GEdge*> edges = (*it)->edges();
std::list<int> ori = (*it)->edgeOrientations();
fprintf(fp, "%d %d ", (*it)->tag(), (int)edges.size());
for(std::list<GEdge*>::iterator ite = edges.begin(); ite != edges.end(); ite++){
fprintf(fp, "%d ", (*ite)->tag());
std::vector<int> tags, signs;
for(std::list<GEdge*>::iterator ite = edges.begin(); ite != edges.end(); ite++)
tags.push_back((*ite)->tag());
for(std::list<int>::iterator ite = ori.begin(); ite != ori.end(); ite++)
signs.push_back(*ite);
if(tags.size() == signs.size()){
for(unsigned int i = 0; i < tags.size(); i++)
tags[i] *= (signs[i] > 0 ? 1 : -1);
}
for(unsigned int i = 0; i < tags.size(); i++)
fprintf(fp, "%d ", tags[i]);
writeMSHPhysicals(fp, *it);
fprintf(fp, "\n");
}
for (GModel::riter it = gm->firstRegion(); it != gm->lastRegion(); ++it) {
std::list<GFace*> faces = (*it)->faces();
std::list<int> ori = (*it)->faceOrientations();
fprintf(fp, "%d %d ", (*it)->tag(), (int)faces.size());
for(std::list<GFace*>::iterator itf = faces.begin(); itf != faces.end(); itf++){
fprintf(fp, "%d ", (*itf)->tag());
std::vector<int> tags, signs;
for(std::list<GFace*>::iterator itf = faces.begin(); itf != faces.end(); itf++)
tags.push_back((*itf)->tag());
for(std::list<int>::iterator itf = ori.begin(); itf != ori.end(); itf++)
signs.push_back(*itf);
if(tags.size() == signs.size()){
for(unsigned int i = 0; i < tags.size(); i++)
tags[i] *= (signs[i] > 0 ? 1 : -1);
}
for(unsigned int i = 0; i < tags.size(); i++)
fprintf(fp, "%d ", tags[i]);
writeMSHPhysicals(fp, *it);
fprintf(fp, "\n");
}
......
......@@ -29,9 +29,9 @@
#define FAST_ELEMENTS 1
extern void writeMSHPeriodicNodes (FILE *fp, std::vector<GEntity*> &entities, bool renumber);
extern void writeMSHPeriodicNodes(FILE *fp, std::vector<GEntity*> &entities, bool renumber);
extern void readMSHPeriodicNodes(FILE *fp, GModel *gm);
extern void writeMSHEntities(FILE *fp, GModel *gm);
static bool getVertices(int num, int *indices, std::map<int, MVertex*> &map,
std::vector<MVertex*> &vertices)
......@@ -927,6 +927,9 @@ int GModel::_writeMSH2(const std::string &name, double version, bool binary,
fprintf(fp, "$EndPhysicalNames\n");
}
if (CTX::instance()->mesh.saveTopology)
writeMSHEntities(fp, this);
if (saveParametric)
fprintf(fp, "$ParametricNodes\n");
else
......
......@@ -65,22 +65,16 @@ static inline double getAlpha(MTriangle* tri, int edj)
}
static inline void crouzeixRaviart(const std::vector<double> &U,std::vector<double> &F){
static inline void crouzeixRaviart(const std::vector<double> &U,std::vector<double> &F)
{
F.resize(3);
double xsi[3] = {0.,1.,0.};
double eta[3] = {0.,0.,1.};
for(int i=0; i<3; i++)
F[i] = U[0] * (1.-2.*eta[i]) + U[1] * (2.*(xsi[i]+eta[i])-1.) + U[2] * (1-2.*xsi[i]);
}
discreteFace::discreteFace(GModel *model, int num) : GFace(model, num)
{
Surface *s = CreateSurface(num, MSH_SURF_DISCRETE);
......@@ -88,13 +82,38 @@ discreteFace::discreteFace(GModel *model, int num) : GFace(model, num)
meshStatistics.status = GFace::DONE;
}
void discreteFace::setBoundEdges(GModel *gm, std::vector<int> tagEdges)
void discreteFace::setBoundEdges(const std::vector<int> &tagEdges)
{
for (std::vector<int>::iterator it = tagEdges.begin(); it != tagEdges.end(); it++){
GEdge *ge = gm->getEdgeByTag(*it);
l_edges.push_back(ge);
l_dirs.push_back(1);
ge->addFace(this);
for (unsigned int i = 0; i != tagEdges.size(); i++){
GEdge *ge = model()->getEdgeByTag(tagEdges[i]);
if(ge){
l_edges.push_back(ge);
l_dirs.push_back(1);
ge->addFace(this);
}
else{
Msg::Error("Unknown model edge %d", tagEdges[i]);
}
}
}
void discreteFace::setBoundEdges(const std::vector<int> &tagEdges,
const std::vector<int> &signEdges)
{
if(signEdges.size() != tagEdges.size()){
Msg::Error("Wrong number of edge signs in setBoundEdges");
setBoundEdges(tagEdges);
}
for (unsigned int i = 0; i != tagEdges.size(); i++){
GEdge *ge = model()->getEdgeByTag(tagEdges[i]);
if(ge){
l_edges.push_back(ge);
l_dirs.push_back(signEdges[i]);
ge->addFace(this);
}
else{
Msg::Error("Unknown model edge %d", tagEdges[i]);
}
}
}
......@@ -525,15 +544,17 @@ void discreteFace::splitDiscreteEdge(GEdge *de , GVertex *gv, discreteEdge* newE
else tagEdges.push_back (geit2->tag());
}
df->l_edges.clear();
df->setBoundEdges (df->model(), tagEdges);
df->setBoundEdges(tagEdges);
}
else{
Msg::Error("splitDiscreteEdge only applies to discrete geometries");
return;
}
else Msg::Fatal("discreteFace::splitDiscreteEdge, This only applies to discrete geometries");
}
}
de->model()->remove(de);
}
void discreteFace::split(triangulation* trian,std::vector<triangulation*> &partition,
int nPartitions)
{
......@@ -979,7 +1000,8 @@ void discreteFace::crossField()
#ifdef HAVE_PETSC
lsys = new linearSystemPETSc<double>;
#else
Msg::Fatal("Petsc is required ");
Msg::Error("Petsc is required for cross fields");
return;
#endif
dofManager<double> myAssembler(lsys);
......@@ -996,7 +1018,6 @@ void discreteFace::crossField()
if (iTri.size()>1)
mini = iTri[0] < iTri[1] ? iTri[0] : iTri[1];
else{
//printf("CL: ed[%f,%f]--[%f,%f]\t Theta: %f \n",ed.getSortedVertex(0)->x(),ed.getSortedVertex(0)->y(),ed.getSortedVertex(1)->x(),ed.getSortedVertex(1)->y(),alpha*180./M_PI);
myAssembler.fixDof(3*mini+j,0,1.); // setting theta and not Theta
myAssembler.fixDof(3*mini+j,1,0.);
}
......
......@@ -44,7 +44,9 @@ class discreteFace : public GFace {
virtual Pair<SVector3, SVector3> firstDer(const SPoint2 &param) const;
virtual void secondDer(const SPoint2 &param,
SVector3 *dudu, SVector3 *dvdv, SVector3 *dudv) const;
void setBoundEdges(GModel *gm, std::vector<int> tagEdges);
void setBoundEdges(const std::vector<int> &tagEdges);
void setBoundEdges(const std::vector<int> &tagEdges,
const std::vector<int> &signEdges);
void findEdges(std::map<MEdge, std::vector<int>, Less_Edge > &map_edges);
void writeGEO(FILE *fp);
void createGeometry();
......
......@@ -21,12 +21,39 @@ discreteRegion::discreteRegion(GModel *model, int num) : GRegion(model, num)
Tree_Add(model->getGEOInternals()->Volumes, &v);
}
void discreteRegion::setBoundFaces(std::set<int> tagFaces)
void discreteRegion::setBoundFaces(const std::set<int> &tagFaces)
{
for (std::set<int>::iterator it = tagFaces.begin() ; it != tagFaces.end();++it){
for (std::set<int>::const_iterator it = tagFaces.begin() ; it != tagFaces.end();++it){
GFace *face = model()->getFaceByTag(*it);
l_faces.push_back(face);
face->addRegion(this);
if(face){
l_faces.push_back(face);
face->addRegion(this);
}
else{
Msg::Error("Unknown model face %d", *it);
}
}
}
void discreteRegion::setBoundFaces(const std::vector<int> &tagFaces,
const std::vector<int> &signFaces)
{
if(tagFaces.size() != signFaces.size()){
Msg::Error("Wrong number of face signs in setBoundFaces");
std::set<int> tags;
tags.insert(tagFaces.begin(), tagFaces.end());
setBoundFaces(tags);
}
for (unsigned int i = 0; i != tagFaces.size(); i++){
GFace *face = model()->getFaceByTag(tagFaces[i]);
if(face){
l_faces.push_back(face);
face->addRegion(this);
l_dirs.push_back(signFaces[i]);
}
else{
Msg::Error("Unknown model face %d", tagFaces[i]);
}
}
}
......
......@@ -15,7 +15,9 @@ class discreteRegion : public GRegion {
discreteRegion(GModel *model, int num);
virtual ~discreteRegion() {}
virtual GeomType geomType() const { return DiscreteVolume; }
void setBoundFaces(std::set<int> tagFaces);
void setBoundFaces(const std::set<int> &tagFaces);
void setBoundFaces(const std::vector<int> &tagFaces,
const std::vector<int> &signFaces);
void findFaces(std::map<MFace, std::vector<int>, Less_Face> &map_faces);
virtual void remesh();
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment