From 304bf733b189a22eedc6feb2ffc6d9b92f9090b9 Mon Sep 17 00:00:00 2001 From: Afeef Date: Mon, 30 Aug 2021 12:17:19 +0200 Subject: [PATCH] Multiple fixes to Gmsh functionality and upgrade to Gmsh 4.8.4 - FIX 1 : Gmsh 3D algorithm was wrongly mapped (Bug ref. spns #24634) the user was unable to choose properly the 3D meshing algorithm. The correction for this is in GMSHPlugin_mesher.cxx, correct mapping is now chosen << mapAlgo3d[_algo3d]) >> - FIX 2 :Compound meshing issue that resulted in extra unwanted edges from the geometry object (Bug ref. #bos 24165) is now fixed. Added a new function SetCompoundMeshVisibility() in GMSHPlugin_Mesher.cxx that helps elimenating these edges while transfer to SMESH. Note this artifact is native to Gmsh. - ADDITIONAL CHANGE 1: 3D algorthims used in Gmsh 4.8.4 have changed (Delaunay, Frontal-Delaunay, MMG3D, R-Tree) are the ones avaliable in 4.8.4. Compared to 4.1.4 no more FrontalHex and Fontal in 3D, also we have added Delaunay in 3D which was missing bedofe. - ADDITIONAL CHANGE 2: Delaunay in 3D is now the default algorithm. --- src/GMSHPlugin/GMSHPlugin_Hypothesis.cxx | 2 +- src/GMSHPlugin/GMSHPlugin_Hypothesis.hxx | 3 +- src/GMSHPlugin/GMSHPlugin_Mesher.cxx | 105 ++++++++++++++++---- src/GMSHPlugin/GMSHPlugin_Mesher.hxx | 1 + src/GUI/GMSHPluginGUI_HypothesisCreator.cxx | 67 ++++++------- src/GUI/GMSHPlugin_msg_en.ts | 8 +- src/GUI/GMSHPlugin_msg_fr.ts | 8 +- 7 files changed, 130 insertions(+), 64 deletions(-) diff --git a/src/GMSHPlugin/GMSHPlugin_Hypothesis.cxx b/src/GMSHPlugin/GMSHPlugin_Hypothesis.cxx index 99634f6..ccbabde 100644 --- a/src/GMSHPlugin/GMSHPlugin_Hypothesis.cxx +++ b/src/GMSHPlugin/GMSHPlugin_Hypothesis.cxx @@ -32,7 +32,7 @@ GMSHPlugin_Hypothesis::GMSHPlugin_Hypothesis (int hypId, SMESH_Gen * gen) : SMESH_Hypothesis(hypId, gen), _algo2d (automatic), - _algo3d (frontal3), + _algo3d (delaunay3), _recomb2DAlgo (standard), _recombineAll (false), _subdivAlgo (none), diff --git a/src/GMSHPlugin/GMSHPlugin_Hypothesis.hxx b/src/GMSHPlugin/GMSHPlugin_Hypothesis.hxx index ded2dbf..dcd0bac 100644 --- a/src/GMSHPlugin/GMSHPlugin_Hypothesis.hxx +++ b/src/GMSHPlugin/GMSHPlugin_Hypothesis.hxx @@ -52,9 +52,8 @@ public: enum Algo3D { + delaunay3, frontal3, - frontaldelaunay, - fontalhex, mmg3d, rtree }; diff --git a/src/GMSHPlugin/GMSHPlugin_Mesher.cxx b/src/GMSHPlugin/GMSHPlugin_Mesher.cxx index c9fc7bb..292db78 100644 --- a/src/GMSHPlugin/GMSHPlugin_Mesher.cxx +++ b/src/GMSHPlugin/GMSHPlugin_Mesher.cxx @@ -257,16 +257,25 @@ void GMSHPlugin_Mesher::SetGmshOptions() //*/ std::map mapAlgo2d; - mapAlgo2d[0]=2; mapAlgo2d[1]=1; mapAlgo2d[2]=5; mapAlgo2d[3]=6; mapAlgo2d[4]=8; mapAlgo2d[5]=9; + mapAlgo2d[0]=2; // Automatic + mapAlgo2d[1]=1; // MeshAdapt + mapAlgo2d[2]=5; // Delaunay + mapAlgo2d[3]=6; // Frontal-Delaunay + mapAlgo2d[4]=8; // DelQuad (Frontal-Delaunay for Quads) + mapAlgo2d[5]=9; // Packing of parallelograms + std::map mapAlgo3d; - mapAlgo3d[0]=1; mapAlgo3d[1]=4; mapAlgo3d[2]=5; mapAlgo3d[3]=6; mapAlgo3d[4]=7; mapAlgo3d[5]=9; + mapAlgo3d[0]=1; // Delaunay + mapAlgo3d[1]=4; // Frontal + mapAlgo3d[2]=7; // MMG3D + mapAlgo3d[3]=9; // R-tree int ok; ok = GmshSetOption("Mesh", "Algorithm" , mapAlgo2d[_algo2d]) ; ASSERT(ok); if ( !_is2d) { - ok = GmshSetOption("Mesh", "Algorithm3D" , mapAlgo2d[_algo3d]) ; + ok = GmshSetOption("Mesh", "Algorithm3D" , mapAlgo3d[_algo3d]) ; ASSERT(ok); } ok = GmshSetOption("Mesh", "RecombinationAlgorithm" , (double)_recomb2DAlgo) ; @@ -310,7 +319,7 @@ void GMSHPlugin_Mesher::CreateGmshCompounds() OCC_Internals* occgeo = _gModel->getOCCInternals(); bool toSynchronize = false; - + for(std::set::const_iterator its = _compounds.begin();its != _compounds.end(); ++its ) { GEOM::GEOM_Object_var aGeomObj; @@ -404,6 +413,60 @@ void GMSHPlugin_Mesher::CreateGmshCompounds() } } +//================================================================================ +/*! + * \brief For a compound mesh set the mesh components to be transmitted to SMESH + */ +//================================================================================ + +#if GMSH_MAJOR_VERSION >=4 && GMSH_MINOR_VERSION >=3 +void GMSHPlugin_Mesher::SetCompoundMeshVisibility() +{ + + // Loop over all faces, if the face belongs to a compound entry then + // for all (boundary) edges whithin the face visibility is set to 0, + // if the face doesn't belong to a compound entry then visibility is + // set to 1 for all its (boundary) edges. Later, in FillSMesh() func + // getVisibility() (returns either 1 or 0) is used to decide weather + // the mesh of edge should be transmitted to SMESH or not. + + for ( GModel::fiter itF = _gModel->firstFace(); itF != _gModel->lastFace(); ++itF ) + { + std::vector< GEdge *> faceEdges = (*itF)->edges(); + + for ( auto itE = faceEdges.begin(); itE != faceEdges.end(); ++itE ) + { + if ( ((*itF)->compound.size()) ) + (*itE)->setVisibility(0); + else + (*itE)->setVisibility(1); + } + } + + + // Loop over all edges, if the edge belongs to a compound entry then + // for all (boundary) vertices whithin the edge visibility is set to + // 0, if the edge doesn't belong to a compound entry then visibility + // is set to 1 for all its (boundary) vertices. Later, in FillSMesh() + // func getVisibility() (returns either 1 or 0) is used to decide we- + // ather the mesh of vertices should be transmitted to SMESH or not. + + for ( GModel::eiter itE = _gModel->firstEdge(); itE != _gModel->lastEdge(); ++itE ) + { + std::vector bndVerticies = (*itE)->vertices(); + + for( auto itV = bndVerticies.begin(); itV != bndVerticies.end(); ++itV ) + { + if(((*itE)->compound.size())) + (*itV)->setVisibility(0); + else + (*itV)->setVisibility(1); + } + } + +} +#endif + //================================================================================ /*! * \brief Write mesh from GModel instance to SMESH instance @@ -453,12 +516,12 @@ void GMSHPlugin_Mesher::FillSMesh() // meshDS->SetMeshElementOnShape(zeroDElement, topoVertex); // } } - + // ADD 1D ELEMENTS for(GModel::eiter it = _gModel->firstEdge(); it != _gModel->lastEdge(); ++it) { GEdge *gEdge = *it; - + // GET topoEdge CORRESPONDING TO gEdge TopoDS_Edge topoEdge; std::vector< ShapeBounds > topoEdges; @@ -708,7 +771,7 @@ void GMSHPlugin_Mesher::FillSMesh() TopoDS_Solid topoSolid = *((TopoDS_Solid*)gRegion->getNativePtr()); // FILL SMESH FOR topoSolid - + //nodes for(unsigned int i = 0; i < gRegion->mesh_vertices.size(); i++) { @@ -719,7 +782,7 @@ void GMSHPlugin_Mesher::FillSMesh() meshDS->SetNodeInVolume( node, topoSolid ); } } - + //elements std::vector verts; for(unsigned int i = 0; i < gRegion->getNumMeshElements(); i++) @@ -895,7 +958,7 @@ void GMSHPlugin_Mesher::FillSMesh() meshDS->SetMeshElementOnShape(volume, topoSolid); } } - + //return 0; } @@ -909,30 +972,30 @@ float GMSHPlugin_Mesher::DistBoundingBox(const SBoundingBox3d& bounds, const SPo { SPoint3 min = bounds.min(); SPoint3 max = bounds.max(); - + float x,y,z; - + if (point.x() < min.x()) x = min.x()-point.x(); else if (point.x() > max.x()) x = point.x()-max.x(); else x = 0.; - + if (point.y() < min.y()) y = min.y()-point.y(); else if (point.y() > max.y()) y = point.y()-max.y(); else y = 0.; - + if (point.z() < min.z()) z = min.z()-point.z(); else if (point.z() > max.z()) z = point.z()-max.z(); else z = 0.; - + return x*x+y*y+z*z; } //================================================================================ @@ -945,7 +1008,7 @@ void GMSHPlugin_Mesher::mymsg::operator()(std::string level, std::string msg) { //MESSAGE("level="<< level.c_str() << ", msg=" << msg.c_str()<< "\n"); printf("level=%s msg=%s\n", level.c_str(), msg.c_str()); - + if(level == "Fatal" || level == "Error") { std::ostringstream oss; @@ -969,7 +1032,7 @@ void GMSHPlugin_Mesher::mymsg::operator()(std::string level, std::string msg) //comment << SMESH_Comment(oss.str); //std::string str = oss.str(); //smError.reset( new SMESH_ComputeError( str )); - + // plutot que de faire de la merde ici, on pourait simplement // remplir une liste pour dire sur quelles entités gmsh se plante // (puis faire le fillsmesh) @@ -996,9 +1059,9 @@ void GMSHPlugin_Mesher::mymsg::operator()(std::string level, std::string msg) bool GMSHPlugin_Mesher::Compute() { MESSAGE("GMSHPlugin_Mesher::Compute"); - + int err = 0; - + GmshInitialize(); SetGmshOptions(); _gModel = new GModel(); @@ -1024,11 +1087,15 @@ bool GMSHPlugin_Mesher::Compute() err = 1; MESSAGE("Unrecoverable error during Generation of Gmsh Mesh"); } - + if (!err) { #if GMSH_MAJOR_VERSION < 4 if (_compounds.size() > 0) _gModel->setCompoundVisibility(); +#endif +#if GMSH_MAJOR_VERSION >=4 && GMSH_MINOR_VERSION >=3 + if (_compounds.size() > 0) + SetCompoundMeshVisibility(); #endif FillSMesh(); } diff --git a/src/GMSHPlugin/GMSHPlugin_Mesher.hxx b/src/GMSHPlugin/GMSHPlugin_Mesher.hxx index 910a708..1fdb36c 100644 --- a/src/GMSHPlugin/GMSHPlugin_Mesher.hxx +++ b/src/GMSHPlugin/GMSHPlugin_Mesher.hxx @@ -102,6 +102,7 @@ class GMSHPLUGIN_EXPORT GMSHPlugin_Mesher void SetGmshOptions(); void CreateGmshCompounds(); + void SetCompoundMeshVisibility(); void FillSMesh(); class mymsg : public GmshMessage diff --git a/src/GUI/GMSHPluginGUI_HypothesisCreator.cxx b/src/GUI/GMSHPluginGUI_HypothesisCreator.cxx index 11227f0..ac0bd8d 100644 --- a/src/GUI/GMSHPluginGUI_HypothesisCreator.cxx +++ b/src/GUI/GMSHPluginGUI_HypothesisCreator.cxx @@ -58,9 +58,8 @@ enum Algo2D enum Algo3D { + delaunay3, frontal3, - frontaldelaunay, - fontalhex, mmg3d, rtree }; @@ -130,11 +129,11 @@ QFrame* GMSHPluginGUI_HypothesisCreator::buildFrame() lay->addWidget( tab ); QWidget* GroupC1 = new QWidget(); tab->insertTab( 0, GroupC1, tr( "SMESH_ARGUMENTS" ) ); - + QGridLayout* aGroupLayout = new QGridLayout( GroupC1 ); aGroupLayout->setSpacing( 6 ); aGroupLayout->setMargin( 11 ); - + int row = 0; myName = 0; if( isCreation() ) @@ -154,20 +153,20 @@ QFrame* GMSHPluginGUI_HypothesisCreator::buildFrame() my2DAlgo->addItems( types2DAlgo ); aGroupLayout->addWidget( my2DAlgo, row, 1 ); row++; - + my3DAlgo = 0; if ( !myIs2D ) { aGroupLayout->addWidget( new QLabel( tr( "GMSH_3D_ALGO" ), GroupC1 ), row, 0 ); my3DAlgo = new QComboBox( GroupC1 ); QStringList types3DAlgo; - types3DAlgo << tr( "GMSH_FRONTAL_DELAUNAY" ) << tr( "GMSH_FRONTAL_HEX" ) << tr( "GMSH_MMG3D" ) << - tr( "GMSH_R_TREE" ); + types3DAlgo << tr("GMSH_DELAUNAY3") << tr( "GMSH_FRONTAL_DELAUNAY" ) << tr( "GMSH_MMG3D" ) << + tr( "GMSH_R_TREE" ); my3DAlgo->addItems( types3DAlgo ); aGroupLayout->addWidget( my3DAlgo, row, 1 ); row++; } - + aGroupLayout->addWidget( new QLabel( tr( "GMSH_2D_RECOMB_ALGO" ), GroupC1 ), row, 0 ); myRecomb2DAlgo = new QComboBox( GroupC1 ); QStringList typesRecomb2DAlgo; @@ -175,11 +174,11 @@ QFrame* GMSHPluginGUI_HypothesisCreator::buildFrame() myRecomb2DAlgo->addItems( typesRecomb2DAlgo ); aGroupLayout->addWidget( myRecomb2DAlgo, row, 1 ); row++; - + myRecombineAll = new QCheckBox( tr( "GMSH_RECOMBINE_ALL" ), GroupC1 ); aGroupLayout->addWidget( myRecombineAll, row, 0 ); row++; - + aGroupLayout->addWidget( new QLabel( tr( "GMSH_SUBDIV_ALGO" ), GroupC1 ), row, 0 ); mySubdivAlgo = new QComboBox( GroupC1 ); QStringList typesSubdivAlgo; @@ -187,7 +186,7 @@ QFrame* GMSHPluginGUI_HypothesisCreator::buildFrame() mySubdivAlgo->addItems( typesSubdivAlgo ); aGroupLayout->addWidget( mySubdivAlgo, row, 1 ); row++; - + aGroupLayout->addWidget( new QLabel( tr( "GMSH_REMESH_ALGO" ), GroupC1 ), row, 0 ); myRemeshAlgo = new QComboBox( GroupC1 ); QStringList typesRemeshAlgo; @@ -195,7 +194,7 @@ QFrame* GMSHPluginGUI_HypothesisCreator::buildFrame() myRemeshAlgo->addItems( typesRemeshAlgo ); aGroupLayout->addWidget( myRemeshAlgo, row, 1 ); row++; - + aGroupLayout->addWidget( new QLabel( tr( "GMSH_REMESH_PARA" ), GroupC1 ), row, 0 ); myRemeshPara = new QComboBox( GroupC1 ); QStringList typesRemeshPara; @@ -203,7 +202,7 @@ QFrame* GMSHPluginGUI_HypothesisCreator::buildFrame() myRemeshPara->addItems( typesRemeshPara ); aGroupLayout->addWidget( myRemeshPara, row, 1 ); row++; - + aGroupLayout->addWidget( new QLabel( tr( "GMSH_SMOOTHING_STEPS" ), GroupC1 ), row, 0 ); mySmouthSteps = new SMESHGUI_SpinBox( GroupC1 ); mySmouthSteps->RangeStepAndValidator( 1, 1000, 1, "length_precision" ); @@ -215,36 +214,36 @@ QFrame* GMSHPluginGUI_HypothesisCreator::buildFrame() mySizeFactor->RangeStepAndValidator( 1e-06, 1e+06, 0.1, "length_precision" ); aGroupLayout->addWidget( mySizeFactor, row, 1 ); row++; - + aGroupLayout->addWidget( new QLabel( tr( "GMSH_MIN_SIZE" ), GroupC1 ), row, 0 ); myMinSize = new SMESHGUI_SpinBox( GroupC1 ); myMinSize->RangeStepAndValidator( 0.0, 1e+22, 1., "length_precision" ); aGroupLayout->addWidget( myMinSize, row, 1 ); row++; - + aGroupLayout->addWidget( new QLabel( tr( "GMSH_MAX_SIZE" ), GroupC1 ), row, 0 ); myMaxSize = new SMESHGUI_SpinBox( GroupC1 ); myMaxSize->RangeStepAndValidator( 0.0, 1e+22, 1e+21, "length_precision" ); aGroupLayout->addWidget( myMaxSize, row, 1 ); row++; - + mySecondOrder = new QCheckBox( tr( "GMSH_SECOND_ORDER" ), GroupC1 ); aGroupLayout->addWidget( mySecondOrder, row, 0 ); - + myUseIncomplElem = new QCheckBox( tr( "GMSH_USE_INCOMPLETE_ELEMENT" ), GroupC1 ); aGroupLayout->addWidget( myUseIncomplElem, row, 1 ); row++; - + connect( mySecondOrder, SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) ); - + // Compounds QWidget* compoundGroup = new QWidget(); tab->insertTab(1, compoundGroup, tr("GMSH_COMPOUND")); - + myCompoundTable = new QTableWidget(0, 2, compoundGroup); QGridLayout* compoundLayout = new QGridLayout(compoundGroup); compoundLayout->addWidget(myCompoundTable, 1, 0, 8, 1); - + QStringList compoundHeaders; compoundHeaders << tr( "GMSH_COMPOUND_ENTRY_COLUMN" ) << tr( "GMSH_COMPOUND_NAME_COLUMN" ); myCompoundTable->setHorizontalHeaderLabels(compoundHeaders); @@ -253,21 +252,21 @@ QFrame* GMSHPluginGUI_HypothesisCreator::buildFrame() myCompoundTable->resizeColumnToContents(1); myCompoundTable->setAlternatingRowColors(true); myCompoundTable->verticalHeader()->hide(); - + QPushButton* addCompoundButton = new QPushButton(tr("GMSH_COMPOUND_ADD"), compoundGroup); compoundLayout->addWidget(addCompoundButton, 1, 1, 1, 1); QFrame *line2 = new QFrame(compoundGroup); - + line2->setFrameShape(QFrame::HLine); line2->setFrameShadow(QFrame::Sunken); compoundLayout->addWidget(line2, 2, 1, 1, 1); - + QPushButton* removeButton = new QPushButton(tr("GMSH_COMPOUND_REMOVE"), compoundGroup); compoundLayout->addWidget(removeButton, 3, 1, 1, 1); connect( addCompoundButton, SIGNAL(clicked()), this, SLOT(onAddCompound())); connect( removeButton, SIGNAL(clicked()), this, SLOT(onRemoveCompound())); - + return fr; } @@ -346,7 +345,7 @@ void GMSHPluginGUI_HypothesisCreator::retrieveParams() const { GmshHypothesisData data; readParamsFromHypo( data ); - + if( myName ) myName->setText( data.myName ); my2DAlgo->setCurrentIndex( data.my2DAlgo ); @@ -379,10 +378,10 @@ void GMSHPluginGUI_HypothesisCreator::retrieveParams() const mySecondOrder->setChecked( data.mySecondOrder ); if ( myUseIncomplElem ) myUseIncomplElem->setChecked( data.myUseIncomplElem ); - + GMSHPluginGUI_HypothesisCreator* that = (GMSHPluginGUI_HypothesisCreator*)this; that->updateWidgets(); - + GeomSelectionTools* geomSelectionTools = that->getGeomSelectionTools(); for (QSet::const_iterator i = myCompoundSet.begin(); i != myCompoundSet.end(); ++i) { @@ -403,12 +402,12 @@ QString GMSHPluginGUI_HypothesisCreator::storeParams() const GmshHypothesisData data; readParamsFromWidgets( data ); storeParamsToHypo( data ); - + QString valStr = tr("GMSH_MAX_SIZE") + " = " + QString::number( data.myMaxSize ) + "; "; valStr += tr("GMSH_MIN_SIZE") + " = " + QString::number( data.myMinSize ) + "; "; if ( data.mySecondOrder ) valStr += tr("GMSH_SECOND_ORDER") + "; "; - + return valStr; } @@ -419,7 +418,7 @@ bool GMSHPluginGUI_HypothesisCreator::readParamsFromHypo( GmshHypothesisData& h_ HypothesisData* data = SMESH::GetHypothesisData( hypType() ); h_data.myName = isCreation() && data ? data->Label : ""; - + h_data.my2DAlgo = (int) h->Get2DAlgo(); if ( !myIs2D ) h_data.my3DAlgo = (int) h->Get3DAlgo(); @@ -438,7 +437,7 @@ bool GMSHPluginGUI_HypothesisCreator::readParamsFromHypo( GmshHypothesisData& h_ h_data.myMaxSizeVar = getVariableName("SetMaxSize"); h_data.mySecondOrder = h->GetSecondOrder(); h_data.myUseIncomplElem = h->GetUseIncomplElem(); - + GMSHPluginGUI_HypothesisCreator* that = (GMSHPluginGUI_HypothesisCreator*)this; GMSHPlugin::string_array_var myEntries = h->GetCompoundOnEntries(); for ( CORBA::ULong i=0 ; ilength() ; i++ ) @@ -446,7 +445,7 @@ bool GMSHPluginGUI_HypothesisCreator::readParamsFromHypo( GmshHypothesisData& h_ QString entry = myEntries[i].in(); that->myCompoundSet.insert(entry); } - + return true; } @@ -530,7 +529,7 @@ bool GMSHPluginGUI_HypothesisCreator::readParamsFromWidgets( GmshHypothesisData& h_data.myMaxSizeVar = myMaxSize->text(); h_data.mySecondOrder = mySecondOrder->isChecked(); h_data.myUseIncomplElem = myUseIncomplElem->isChecked(); - + // ne semble pas utile dans la mesure ou myCompoundSet n'a pas besoin d'etre modifier /* GMSHPluginGUI_HypothesisCreator* that = (GMSHPluginGUI_HypothesisCreator*)this; diff --git a/src/GUI/GMSHPlugin_msg_en.ts b/src/GUI/GMSHPlugin_msg_en.ts index 98d0638..b252726 100644 --- a/src/GUI/GMSHPlugin_msg_en.ts +++ b/src/GUI/GMSHPlugin_msg_en.ts @@ -84,12 +84,12 @@ 3D Algorithm - GMSH_FRONTAL_DELAUNAY - Frontal Delaunay + GMSH_DELAUNAY3 + Delaunay - GMSH_FRONTAL_HEX - Frontal Hex + GMSH_FRONTAL_DELAUNAY + Frontal Delaunay GMSH_MMG3D diff --git a/src/GUI/GMSHPlugin_msg_fr.ts b/src/GUI/GMSHPlugin_msg_fr.ts index b796525..f119c82 100644 --- a/src/GUI/GMSHPlugin_msg_fr.ts +++ b/src/GUI/GMSHPlugin_msg_fr.ts @@ -88,12 +88,12 @@ Algorithme 3D - GMSH_FRONTAL_DELAUNAY - Frontal Delaunay + GMSH_DELAUNAY3 + Delaunay - GMSH_FRONTAL_HEX - Frontal Hex + GMSH_FRONTAL_DELAUNAY + Frontal Delaunay GMSH_MMG3D -- 2.30.2