From: akondrat Date: Mon, 12 Dec 2022 04:55:44 +0000 (+0000) Subject: [EDF] (2022-T3) Creation of 3D mesh with GMSH based on 2D mesh created with another... X-Git-Tag: V9_11_0b1~1 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=refs%2Fheads%2FCR32524;p=plugins%2Fgmshplugin.git [EDF] (2022-T3) Creation of 3D mesh with GMSH based on 2D mesh created with another algorithm --- diff --git a/idl/GMSHPlugin_Algorithm.idl b/idl/GMSHPlugin_Algorithm.idl index cd210c5..9ac8730 100644 --- a/idl/GMSHPlugin_Algorithm.idl +++ b/idl/GMSHPlugin_Algorithm.idl @@ -37,6 +37,13 @@ module GMSHPlugin */ interface GMSHPlugin_GMSH : SMESH::SMESH_3D_Algo { + }; + + /*! + * GMSHPlugin_GMSH_3D: interface of "Gmsh" algorithm + */ + interface GMSHPlugin_GMSH_3D : SMESH::SMESH_3D_Algo + { }; /*! diff --git a/resources/GMSHPlugin.xml b/resources/GMSHPlugin.xml index a73d0ab..b4eb3eb 100644 --- a/resources/GMSHPlugin.xml +++ b/resources/GMSHPlugin.xml @@ -17,12 +17,16 @@ label-id="Gmsh Parameters" icon-id="gmsh.png" dim="2"/> + GMSH_Parameters=Parameters() - + GMSH_Parameters_2D=Parameters() - + + + + GMSH_3D=Tetrahedron(algo=smeshBuilder.GMSH_3D) + GMSH_Parameters_3D=Parameters() + + + diff --git a/src/GMSHPlugin/CMakeLists.txt b/src/GMSHPlugin/CMakeLists.txt index 83153dc..aa8d403 100644 --- a/src/GMSHPlugin/CMakeLists.txt +++ b/src/GMSHPlugin/CMakeLists.txt @@ -67,12 +67,16 @@ SET(_link_LIBRARIES SET(GMSHEngine_HEADERS GMSHPlugin_GMSH_2D.hxx GMSHPlugin_GMSH_2D_i.hxx + GMSHPlugin_GMSH_3D.hxx + GMSHPlugin_GMSH_3D_i.cxx GMSHPlugin_GMSH.hxx GMSHPlugin_GMSH_i.hxx GMSHPlugin_Hypothesis.hxx GMSHPlugin_Hypothesis_i.hxx GMSHPlugin_Hypothesis_2D.hxx GMSHPlugin_Hypothesis_2D_i.hxx + GMSHPlugin_Hypothesis_3D.hxx + GMSHPlugin_Hypothesis_3D_i.hxx GMSHPlugin_Mesher.hxx GMSHPlugin_Defs.hxx ) @@ -83,12 +87,16 @@ SET(GMSHEngine_HEADERS SET(GMSHEngine_SOURCES GMSHPlugin_GMSH_2D.cxx GMSHPlugin_GMSH_2D_i.cxx + GMSHPlugin_GMSH_3D.cxx + GMSHPlugin_GMSH_3D_i.cxx GMSHPlugin_GMSH.cxx GMSHPlugin_GMSH_i.cxx GMSHPlugin_Hypothesis.cxx GMSHPlugin_Hypothesis_i.cxx GMSHPlugin_Hypothesis_2D.cxx GMSHPlugin_Hypothesis_2D_i.cxx + GMSHPlugin_Hypothesis_3D.cxx + GMSHPlugin_Hypothesis_3D_i.cxx GMSHPlugin_Mesher.cxx GMSHPlugin_i.cxx ) diff --git a/src/GMSHPlugin/GMSHPluginBuilder.py b/src/GMSHPlugin/GMSHPluginBuilder.py index 618ed5f..d3e7b29 100644 --- a/src/GMSHPlugin/GMSHPluginBuilder.py +++ b/src/GMSHPlugin/GMSHPluginBuilder.py @@ -34,8 +34,9 @@ except ImportError: pass # Types of algorithms -GMSH = "GMSH" -GMSH_2D = "GMSH_2D" +GMSH = "GMSH" +GMSH_3D = "GMSH_3D" +GMSH_2D = "GMSH_2D" ## Base of all GMSH algorithms. # @@ -57,6 +58,8 @@ class GMSH_Algorithm(Mesh_Algorithm): hypType = "GMSH_Parameters_2D" elif self.algoType == GMSH: hypType = "GMSH_Parameters" + elif self.algoType == GMSH_3D: + hypType = "GMSH_Parameters_3D" if self.params and self.params.GetName() != hypType: self.mesh.RemoveHypothesis( self.params, self.geom ) @@ -73,3 +76,12 @@ class GMSH_2D_Algorithm(GMSH_Algorithm): ## Private constructor. def __init__(self, mesh, geom=0): GMSH_Algorithm.__init__(self, mesh, geom) + +class GMSH_3D_Algorithm(GMSH_Algorithm): + + meshMethod = "Tetrahedron" + algoType = GMSH_3D + + ## Private constructor. + def __init__(self, mesh, geom=0): + GMSH_Algorithm.__init__(self, mesh, geom) diff --git a/src/GMSHPlugin/GMSHPlugin_GMSH.cxx b/src/GMSHPlugin/GMSHPlugin_GMSH.cxx index 1400ff6..be45768 100644 --- a/src/GMSHPlugin/GMSHPlugin_GMSH.cxx +++ b/src/GMSHPlugin/GMSHPlugin_GMSH.cxx @@ -110,7 +110,7 @@ bool GMSHPlugin_GMSH::CheckHypothesis (SMESH_Mesh& aMes bool GMSHPlugin_GMSH::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) { - GMSHPlugin_Mesher mesher(&aMesh, aShape,/*2d=*/false); + GMSHPlugin_Mesher mesher(&aMesh, aShape,/*2d=*/false, false); mesher.SetParameters(dynamic_cast(_hypothesis)); return mesher.Compute(); } diff --git a/src/GMSHPlugin/GMSHPlugin_GMSH_2D.cxx b/src/GMSHPlugin/GMSHPlugin_GMSH_2D.cxx index d3f19f9..c950577 100644 --- a/src/GMSHPlugin/GMSHPlugin_GMSH_2D.cxx +++ b/src/GMSHPlugin/GMSHPlugin_GMSH_2D.cxx @@ -111,7 +111,7 @@ bool GMSHPlugin_GMSH_2D::CheckHypothesis bool GMSHPlugin_GMSH_2D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) { - GMSHPlugin_Mesher mesher(&aMesh, aShape,/*2d=*/true); + GMSHPlugin_Mesher mesher(&aMesh, aShape,/*2d=*/true, false); mesher.SetParameters(dynamic_cast(_hypothesis)); return mesher.Compute(); } diff --git a/src/GMSHPlugin/GMSHPlugin_GMSH_3D.cxx b/src/GMSHPlugin/GMSHPlugin_GMSH_3D.cxx new file mode 100644 index 0000000..e392777 --- /dev/null +++ b/src/GMSHPlugin/GMSHPlugin_GMSH_3D.cxx @@ -0,0 +1,143 @@ +// Copyright (C) 2012-2015 ALNEOS +// Copyright (C) 2016-2022 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.alneos.com/ or email : contact@alneos.fr +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#include "GMSHPlugin_GMSH_3D.hxx" +#include "GMSHPlugin_Hypothesis_2D.hxx" +#include "GMSHPlugin_Mesher.hxx" + +#include +#include +#include +#include + +#include + +using namespace std; + +//============================================================================= +/*! + * + */ +//============================================================================= + +GMSHPlugin_GMSH_3D::GMSHPlugin_GMSH_3D(int hypId, SMESH_Gen* gen) + : SMESH_3D_Algo(hypId, gen) +{ + MESSAGE("GMSHPlugin_GMSH_3D::GMSHPlugin_GMSH_3D"); + _name = "GMSH_3D"; + _shapeType = (1 << TopAbs_SOLID); // 1 bit /shape type + _compatibleHypothesis.push_back("GMSH_Parameters_3D"); + _onlyUnaryInput = false; + _hypothesis = NULL; + _supportSubmeshes = true; + + _requireShape = false; // can work without shape +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +GMSHPlugin_GMSH_3D::~GMSHPlugin_GMSH_3D() +{ + MESSAGE("GMSHPlugin_GMSH_3D::~GMSHPlugin_GMSH_3D"); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool GMSHPlugin_GMSH_3D::CheckHypothesis + (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus) +{ + MESSAGE("GMSHPlugin_GMSH::CheckHypothesis"); + + _hypothesis = NULL; + + const list& hyps = GetUsedHypothesis(aMesh, aShape); + int nbHyp = hyps.size(); + if (!nbHyp) + { + aStatus = SMESH_Hypothesis::HYP_OK; + return true; // can work with no hypothesis + } + // use only the first hypothesis + const SMESHDS_Hypothesis* theHyp = hyps.front(); + + string hypName = theHyp->GetName(); + if ( find( _compatibleHypothesis.begin(), _compatibleHypothesis.end(), + hypName ) != _compatibleHypothesis.end() ) + { + _hypothesis = theHyp; + aStatus = SMESH_Hypothesis::HYP_OK; + } + else + { + aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE; + } + + return aStatus == SMESH_Hypothesis::HYP_OK; +} + +//============================================================================= +/*! + *Here we are going to use the GMSH mesher + */ +//============================================================================= + +bool GMSHPlugin_GMSH_3D::Compute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape) +{ + GMSHPlugin_Mesher mesher(&aMesh, aShape,/*2d=*/false, true); + mesher.SetParameters(dynamic_cast(_hypothesis)); + + return mesher.Compute(); +} + +#ifdef WITH_SMESH_CANCEL_COMPUTE +void GMSHPlugin_GMSH_3D::CancelCompute() +{} +#endif + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool GMSHPlugin_GMSH_3D::Evaluate(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + MapShapeNbElems& aResMap) +{ + std::vector aResVec(SMDSEntity_Last); + for(smIdType i=SMDSEntity_Node; iGetComputeError(); + smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Evaluation is not implemented",this)); + + return true; +} diff --git a/src/GMSHPlugin/GMSHPlugin_GMSH_3D.hxx b/src/GMSHPlugin/GMSHPlugin_GMSH_3D.hxx new file mode 100644 index 0000000..9514ef0 --- /dev/null +++ b/src/GMSHPlugin/GMSHPlugin_GMSH_3D.hxx @@ -0,0 +1,55 @@ +// Copyright (C) 2012-2015 ALNEOS +// Copyright (C) 2016-2022 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.alneos.com/ or email : contact@alneos.fr +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#ifndef _GMSHPlugin_GMSH_3D_HXX_ +#define _GMSHPlugin_GMSH_3D_HXX_ + +#include "GMSHPlugin_Defs.hxx" + +#include "SMESH_Algo.hxx" +#include "SMESH_subMesh.hxx" +#include "SMESH_Mesh.hxx" + +class GMSHPLUGIN_EXPORT GMSHPlugin_GMSH_3D: public SMESH_3D_Algo +{ +public: + GMSHPlugin_GMSH_3D(int hypId, SMESH_Gen* gen); + virtual ~GMSHPlugin_GMSH_3D(); + + virtual bool CheckHypothesis(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus); + + virtual bool Compute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape); + +#ifdef WITH_SMESH_CANCEL_COMPUTE + virtual void CancelCompute(); +#endif + + virtual bool Evaluate(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + MapShapeNbElems& aResMap); + +protected: + const SMESHDS_Hypothesis* _hypothesis; +}; + +#endif diff --git a/src/GMSHPlugin/GMSHPlugin_GMSH_3D_i.cxx b/src/GMSHPlugin/GMSHPlugin_GMSH_3D_i.cxx new file mode 100644 index 0000000..09fbee9 --- /dev/null +++ b/src/GMSHPlugin/GMSHPlugin_GMSH_3D_i.cxx @@ -0,0 +1,74 @@ +// Copyright (C) 2012-2015 ALNEOS +// Copyright (C) 2016-2022 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.alneos.com/ or email : contact@alneos.fr +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#include "GMSHPlugin_GMSH_3D_i.hxx" +#include "SMESH_Gen.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +using namespace std; + +//============================================================================= +/*! + * GMSHPlugin_GMSH_2D_i::GMSHPlugin_GMSH_2D_i + * + * Constructor + */ +//============================================================================= + +GMSHPlugin_GMSH_3D_i::GMSHPlugin_GMSH_3D_i( PortableServer::POA_ptr thePOA, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ), + SMESH_3D_Algo_i( thePOA ) +{ + MESSAGE( "GMSHPlugin_GMSH_3D_i::GMSHPlugin_GMSH_3D_i" ); + myBaseImpl = new ::GMSHPlugin_GMSH_3D( theGenImpl->GetANewId(), + theGenImpl ); +} + +//============================================================================= +/*! + * GMSHPlugin_GMSH_2D_i::~GMSHPlugin_GMSH_2D_i + * + * Destructor + */ +//============================================================================= + +GMSHPlugin_GMSH_3D_i::~GMSHPlugin_GMSH_3D_i() +{ + MESSAGE( "GMSHPlugin_GMSH_3D_i::~GMSHPlugin_GMSH_3D_i" ); +} + +//============================================================================= +/*! + * GMSHPlugin_GMSH_2D_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::GMSHPlugin_GMSH_3D* GMSHPlugin_GMSH_3D_i::GetImpl() +{ + MESSAGE( "GMSHPlugin_GMSH_3D_i::GetImpl" ); + return ( ::GMSHPlugin_GMSH_3D* )myBaseImpl; +} diff --git a/src/GMSHPlugin/GMSHPlugin_GMSH_3D_i.hxx b/src/GMSHPlugin/GMSHPlugin_GMSH_3D_i.hxx new file mode 100644 index 0000000..f010785 --- /dev/null +++ b/src/GMSHPlugin/GMSHPlugin_GMSH_3D_i.hxx @@ -0,0 +1,49 @@ +// Copyright (C) 2012-2015 ALNEOS +// Copyright (C) 2016-2022 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.alneos.com/ or email : contact@alneos.fr +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#ifndef _GMSHPlugin_GMSH_3D_I_HXX_ +#define _GMSHPlugin_GMSH_3D_I_HXX_ + +#include "GMSHPlugin_Defs.hxx" + +#include +#include CORBA_SERVER_HEADER(GMSHPlugin_Algorithm) + +#include "SMESH_3D_Algo_i.hxx" +#include "GMSHPlugin_GMSH_3D.hxx" + +// ====================================================== +// GMSH 3d algorithm +// ====================================================== +class GMSHPLUGIN_EXPORT GMSHPlugin_GMSH_3D_i: + public virtual SMESH_3D_Algo_i +{ +public: + // Constructor + GMSHPlugin_GMSH_3D_i( PortableServer::POA_ptr thePOA, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~GMSHPlugin_GMSH_3D_i(); + + // Get implementation + ::GMSHPlugin_GMSH_3D* GetImpl(); +}; + +#endif diff --git a/src/GMSHPlugin/GMSHPlugin_Hypothesis_3D.cxx b/src/GMSHPlugin/GMSHPlugin_Hypothesis_3D.cxx new file mode 100644 index 0000000..833216f --- /dev/null +++ b/src/GMSHPlugin/GMSHPlugin_Hypothesis_3D.cxx @@ -0,0 +1,40 @@ +// Copyright (C) 2012-2015 ALNEOS +// Copyright (C) 2016-2022 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.alneos.com/ or email : contact@alneos.fr +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#include "GMSHPlugin_Hypothesis_3D.hxx" +#include + +//#include + +using namespace std; + +//============================================================================= +/*! + * + */ +//============================================================================= +GMSHPlugin_Hypothesis_3D::GMSHPlugin_Hypothesis_3D (int hypId, SMESH_Gen * gen) + : GMSHPlugin_Hypothesis(hypId, gen) + +{ + _name = "GMSH_Parameters_3D"; + _param_algo_dim = 3; +} + diff --git a/src/GMSHPlugin/GMSHPlugin_Hypothesis_3D.hxx b/src/GMSHPlugin/GMSHPlugin_Hypothesis_3D.hxx new file mode 100644 index 0000000..557b8bd --- /dev/null +++ b/src/GMSHPlugin/GMSHPlugin_Hypothesis_3D.hxx @@ -0,0 +1,41 @@ +// Copyright (C) 2012-2015 ALNEOS +// Copyright (C) 2016-2022 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.alneos.com/ or email : contact@alneos.fr +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#ifndef _GMSHPlugin_Hypothesis_2D_HXX_ +#define _GMSHPlugin_Hypothesis_2D_HXX_ + +#include "GMSHPlugin_Defs.hxx" + +#include "GMSHPlugin_Hypothesis.hxx" +#include "Utils_SALOME_Exception.hxx" + +// Parameters for work of GMSH. +// This class is just to give 2D dimension, actually +// it inherits all behaviour of the parent + +class GMSHPLUGIN_EXPORT GMSHPlugin_Hypothesis_3D: public GMSHPlugin_Hypothesis +{ +public: + + GMSHPlugin_Hypothesis_3D(int hypId, SMESH_Gen * gen); + +}; + +#endif diff --git a/src/GMSHPlugin/GMSHPlugin_Hypothesis_3D_i.cxx b/src/GMSHPlugin/GMSHPlugin_Hypothesis_3D_i.cxx new file mode 100644 index 0000000..c3fff0f --- /dev/null +++ b/src/GMSHPlugin/GMSHPlugin_Hypothesis_3D_i.cxx @@ -0,0 +1,75 @@ +// Copyright (C) 2012-2015 ALNEOS +// Copyright (C) 2016-2022 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.alneos.com/ or email : contact@alneos.fr +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#include "GMSHPlugin_Hypothesis_3D_i.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_PythonDump.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +using namespace std; + +//============================================================================= +/*! + * GMSHPlugin_Hypothesis_3D_i::GMSHPlugin_Hypothesis_3D_i + * + * Constructor + */ +//============================================================================= +GMSHPlugin_Hypothesis_3D_i:: +GMSHPlugin_Hypothesis_3D_i (PortableServer::POA_ptr thePOA, + ::SMESH_Gen* theGenImpl) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + GMSHPlugin_Hypothesis_i( thePOA, theGenImpl ) +{ + MESSAGE( "GMSHPlugin_Hypothesis_3D_i::GMSHPlugin_Hypothesis_3D_i" ); + if (myBaseImpl) + delete (::GMSHPlugin_Hypothesis*)myBaseImpl; + myBaseImpl = new ::GMSHPlugin_Hypothesis_3D (theGenImpl->GetANewId(), + theGenImpl); +} + +//============================================================================= +/*! + * GMSHPlugin_Hypothesis_2D_i::~GMSHPlugin_Hypothesis_2D_i + * + * Destructor + */ +//============================================================================= +GMSHPlugin_Hypothesis_3D_i::~GMSHPlugin_Hypothesis_3D_i() +{ + MESSAGE( "GMSHPlugin_Hypothesis_3D_i::~GMSHPlugin_Hypothesis_3D_i" ); +} + +//================================================================================ +/*! + * \brief Verify whether hypothesis supports given entity type + * \param type - dimension (see SMESH::Dimension enumeration) + * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise + * + * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration) + */ +//================================================================================ +CORBA::Boolean GMSHPlugin_Hypothesis_3D_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_3D; +} diff --git a/src/GMSHPlugin/GMSHPlugin_Hypothesis_3D_i.hxx b/src/GMSHPlugin/GMSHPlugin_Hypothesis_3D_i.hxx new file mode 100644 index 0000000..ca86448 --- /dev/null +++ b/src/GMSHPlugin/GMSHPlugin_Hypothesis_3D_i.hxx @@ -0,0 +1,51 @@ +// Copyright (C) 2012-2015 ALNEOS +// Copyright (C) 2016-2022 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.alneos.com/ or email : contact@alneos.fr +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#ifndef _GMSHPlugin_Hypothesis_3D_i_HXX_ +#define _GMSHPlugin_Hypothesis_3D_i_HXX_ + +#include "GMSHPlugin_Defs.hxx" + +#include +#include CORBA_SERVER_HEADER(GMSHPlugin_Algorithm) + +#include "GMSHPlugin_Hypothesis_i.hxx" +#include "GMSHPlugin_Hypothesis_3D.hxx" + +class SMESH_Gen; + +// GMSHPlugin parameters hypothesis (2D case) + +class GMSHPLUGIN_EXPORT GMSHPlugin_Hypothesis_3D_i: + public virtual POA_GMSHPlugin::GMSHPlugin_Hypothesis, + public GMSHPlugin_Hypothesis_i +{ + public: + // Constructor + GMSHPlugin_Hypothesis_3D_i (PortableServer::POA_ptr thePOA, + ::SMESH_Gen* theGenImpl); + // Destructor + virtual ~GMSHPlugin_Hypothesis_3D_i(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); +}; + +#endif diff --git a/src/GMSHPlugin/GMSHPlugin_Mesher.cxx b/src/GMSHPlugin/GMSHPlugin_Mesher.cxx index 92b5030..b152cc2 100644 --- a/src/GMSHPlugin/GMSHPlugin_Mesher.cxx +++ b/src/GMSHPlugin/GMSHPlugin_Mesher.cxx @@ -32,7 +32,9 @@ #include #include #include +#include +#include #include #include @@ -152,10 +154,12 @@ namespace GMSHPlugin_Mesher::GMSHPlugin_Mesher (SMESH_Mesh* mesh, const TopoDS_Shape& aShape, - bool is2D) + bool is2D, + bool is3D) : _mesh (mesh), _shape (aShape), - _is2d (is2D) + _is2d (is2D), + _is3d (is3D) { // il faudra peut être mettre un truc par defaut si l'utilisateur ne rentre rien en para //defaultParameters(); @@ -230,10 +234,146 @@ void GMSHPlugin_Mesher::SetMaxThreadsGmsh() //================================================================================ /*! - * \brief Set Gmsh Options + * \brief Initialize GMSH model */ -//================================================================================ + //================================================================================ +void GMSHPlugin_Mesher::FillGMSHMesh() +{ + gmsh::initialize(); + gmsh::model::add("mesh"); + + SMESHDS_Mesh* meshDS = _mesh->GetMeshDS(); + + int aNbOfNodes = 0; + int aNbOfCurves = 0; + int aNbOfLines = 0; + std::vector aTrinagle(3, 0); + + const int invalid_ID = -1; + + // typedef for maps + typedef map< const SMDS_MeshNode*, int, TIDCompare > TNodeToIDMap; + typedef TNodeToIDMap::value_type TN2ID; + typedef map, int> TLineToIDMap; + TNodeToIDMap aNodeToID; + TLineToIDMap aLineToID; + + TopAbs_ShapeEnum aMainType = _mesh->GetShapeToMesh().ShapeType(); + bool aCheckReverse = (aMainType == TopAbs_COMPOUND || aMainType == TopAbs_COMPSOLID); + + SMESH_MesherHelper aHelper(*_mesh); + SMESH_ProxyMesh::Ptr aProxyMesh(new SMESH_ProxyMesh(*_mesh)); + if (_mesh->NbQuadrangles() > 0) + { + StdMeshers_QuadToTriaAdaptor* Adaptor = new StdMeshers_QuadToTriaAdaptor; + Adaptor->Compute(*_mesh, _shape, aProxyMesh.get()); + aProxyMesh.reset(Adaptor); + } + + std::map listElements; + for (TopExp_Explorer exFa(_shape, TopAbs_FACE); exFa.More(); exFa.Next()) + { + const TopoDS_Shape& aShapeFace = exFa.Current(); + int faceID = meshDS->ShapeToIndex(aShapeFace); + + bool isRev = false; + if (aCheckReverse && aHelper.NbAncestors(aShapeFace, *_mesh, _shape.ShapeType()) > 1) + // IsReversedSubMesh() can work wrong on strongly curved faces, + // so we use it as less as possible + isRev = aHelper.IsReversedSubMesh(TopoDS::Face(aShapeFace)); + + const SMESHDS_SubMesh* aSubMeshDSFace = aProxyMesh->GetSubMesh(aShapeFace); + if (!aSubMeshDSFace) continue; + + SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements(); + if (aHelper.IsQuadraticSubMesh(_shape) && + dynamic_cast(aSubMeshDSFace)) + { + // add medium nodes of proxy triangles to helper + while (iteratorElem->more()) + aHelper.AddTLinks(static_cast(iteratorElem->next())); + + iteratorElem = aSubMeshDSFace->GetElements(); + } + while (iteratorElem->more()) // loop on elements on a geom face + { + // check mesh face + const SMDS_MeshElement* elem = iteratorElem->next(); + if (!elem) + return; + if (elem->NbCornerNodes() != 3) + return; + listElements[elem] = isRev; + } + } + + for (auto const& ls : listElements) + { + // Add nodes of triangles and triangles them-selves to netgen mesh + // add three nodes of + bool hasDegen = false; + for (int iN = 0; iN < 3; ++iN) + { + const SMDS_MeshNode* aNode = ls.first->GetNode(iN); + const int shapeID = aNode->getshapeId(); + if (aNode->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE && + aHelper.IsDegenShape(shapeID)) + { + // ignore all nodes on degeneraged edge and use node on its vertex instead + TopoDS_Shape vertex = TopoDS_Iterator(meshDS->IndexToShape(shapeID)).Value(); + aNode = SMESH_Algo::VertexNode(TopoDS::Vertex(vertex), meshDS); + hasDegen = true; + } + int& ngID = aNodeToID.insert(TN2ID(aNode, invalid_ID)).first->second; + if (ngID == invalid_ID) + { + ngID = ++aNbOfNodes; + gmsh::model::occ::addPoint(aNode->X(), aNode->Y(), aNode->Z(), 1.e-2, ngID); + } + aTrinagle[ls.second ? 2 - iN : iN] = ngID; + } + // add triangle + if (hasDegen && (aTrinagle[0] == aTrinagle[1] || + aTrinagle[0] == aTrinagle[2] || + aTrinagle[2] == aTrinagle[1])) + continue; + + + std::vector LinesID(3, 0); + for (int anIndex = 0; anIndex < 3; ++anIndex) + { + int aNextIndex = (anIndex + 1) % 3; + if (aLineToID.find({ aTrinagle[anIndex], aTrinagle[aNextIndex] }) == aLineToID.end() + && aLineToID.find({ aTrinagle[aNextIndex], aTrinagle[anIndex] }) == aLineToID.end()) + { + LinesID[anIndex] = aLineToID.insert({ { aTrinagle[aNextIndex], aTrinagle[anIndex] }, ++aNbOfLines }).first->second; + gmsh::model::occ::addLine(aTrinagle[anIndex], aTrinagle[aNextIndex], LinesID[anIndex]); + } + else + { + LinesID[anIndex] = aLineToID.find({ aTrinagle[anIndex], aTrinagle[aNextIndex] })->second; + if (LinesID[anIndex] == 0) + LinesID[anIndex] = aLineToID.find({ aTrinagle[aNextIndex], aTrinagle[anIndex] })->second; + + } + } + if (!aProxyMesh->IsTemporary(ls.first)) + swap(aTrinagle[1], aTrinagle[2]); + + int aTag = gmsh::model::occ::addCurveLoop(LinesID); + } + + // Generate 1D and 2D mesh + _gModel->mesh( /*dim=*/ 1); + Set1DSubMeshes(_gModel); + _gModel->mesh( /*dim=*/ 2); +} +//================================================================================ +/*! + * \brief Set Gmsh Options + */ + //================================================================================ void GMSHPlugin_Mesher::SetGmshOptions() { MESSAGE("GMSHPlugin_Mesher::SetGmshOptions"); @@ -1132,30 +1272,40 @@ bool GMSHPlugin_Mesher::Compute() if (_compounds.size() > 0) CreateGmshCompounds(); try { - //Msg::SetVerbosity(100); - //CTX::instance()->mesh.maxNumThreads1D=1; - HideComputedEntities( _gModel ); + HideComputedEntities(_gModel); + if (_is3d) + { + FillGMSHMesh(); - _gModel->mesh( /*dim=*/ 1 ); + Set2DSubMeshes(_gModel); - Set1DSubMeshes( _gModel ); + _gModel->mesh( /*dim=*/ 3); + } + else + { + //Msg::SetVerbosity(100); + //CTX::instance()->mesh.maxNumThreads1D=1; - //_gModel->writeUNV("/tmp/1D.unv", 1,0,0); - //CTX::instance()->mesh.maxNumThreads2D=1; + _gModel->mesh( /*dim=*/ 1); - _gModel->mesh( /*dim=*/ 2 ); + Set1DSubMeshes(_gModel); - if ( !_is2d ) - { - Set2DSubMeshes( _gModel ); + //_gModel->writeUNV("/tmp/1D.unv", 1,0,0); + //CTX::instance()->mesh.maxNumThreads2D=1; - //CTX::instance()->mesh.maxNumThreads3D=1; + _gModel->mesh( /*dim=*/ 2); - _gModel->mesh( /*dim=*/ 3 ); - } - RestoreVisibility( _gModel ); + if (!_is2d) + { + Set2DSubMeshes(_gModel); + //CTX::instance()->mesh.maxNumThreads3D=1; + + _gModel->mesh( /*dim=*/ 3); + } + RestoreVisibility(_gModel); + } #ifdef WITH_SMESH_CANCEL_COMPUTE #endif diff --git a/src/GMSHPlugin/GMSHPlugin_Mesher.hxx b/src/GMSHPlugin/GMSHPlugin_Mesher.hxx index 4e5bd4e..fe9599d 100644 --- a/src/GMSHPlugin/GMSHPlugin_Mesher.hxx +++ b/src/GMSHPlugin/GMSHPlugin_Mesher.hxx @@ -68,7 +68,7 @@ class GMSHPLUGIN_EXPORT GMSHPlugin_Mesher public: // ---------- PUBLIC METHODS ---------- - GMSHPlugin_Mesher (SMESH_Mesh* mesh, const TopoDS_Shape& aShape, bool is2D); + GMSHPlugin_Mesher (SMESH_Mesh* mesh, const TopoDS_Shape& aShape, bool is2D, bool is3D); void SetParameters(const GMSHPlugin_Hypothesis* hyp); @@ -78,6 +78,8 @@ class GMSHPLUGIN_EXPORT GMSHPlugin_Mesher static float DistBoundingBox(const SBoundingBox3d& bounds, const SPoint3& point); + void FillGMSHMesh(); + private: SMESH_Mesh* _mesh; const TopoDS_Shape& _shape; @@ -93,6 +95,7 @@ class GMSHPLUGIN_EXPORT GMSHPlugin_Mesher double _minSize, _maxSize; bool _secondOrder, _useIncomplElem; bool _is2d; + bool _is3d; GModel* _gModel; #if GMSH_MAJOR_VERSION >=4 && GMSH_MINOR_VERSION >=3 double _maxThreads; diff --git a/src/GMSHPlugin/GMSHPlugin_i.cxx b/src/GMSHPlugin/GMSHPlugin_i.cxx index 0c37213..6671cb1 100644 --- a/src/GMSHPlugin/GMSHPlugin_i.cxx +++ b/src/GMSHPlugin/GMSHPlugin_i.cxx @@ -22,8 +22,10 @@ #include "GMSHPlugin_Hypothesis_i.hxx" #include "GMSHPlugin_Hypothesis_2D_i.hxx" +#include "GMSHPlugin_Hypothesis_3D_i.hxx" #include "GMSHPlugin_GMSH_i.hxx" #include "GMSHPlugin_GMSH_2D_i.hxx" +#include "GMSHPlugin_GMSH_3D_i.hxx" template class GMSHPlugin_Creator_i:public HypothesisCreator_i { @@ -53,11 +55,15 @@ extern "C" aCreator = new GMSHPlugin_Creator_i; else if (strcmp(aHypName, "GMSH_2D") == 0) aCreator = new GMSHPlugin_Creator_i; + else if (strcmp(aHypName, "GMSH_3D") == 0) + aCreator = new GMSHPlugin_Creator_i; // Hypotheses else if (strcmp(aHypName, "GMSH_Parameters") == 0) aCreator = new GMSHPlugin_Creator_i; else if (strcmp(aHypName, "GMSH_Parameters_2D") == 0) aCreator = new GMSHPlugin_Creator_i; + else if (strcmp(aHypName, "GMSH_Parameters_3D") == 0) + aCreator = new GMSHPlugin_Creator_i; return aCreator; } diff --git a/src/GUI/GMSHPluginGUI_HypothesisCreator.cxx b/src/GUI/GMSHPluginGUI_HypothesisCreator.cxx index a048c16..d409cc5 100644 --- a/src/GUI/GMSHPluginGUI_HypothesisCreator.cxx +++ b/src/GUI/GMSHPluginGUI_HypothesisCreator.cxx @@ -114,6 +114,7 @@ GMSHPluginGUI_HypothesisCreator::GMSHPluginGUI_HypothesisCreator( const QString& myGeomSelectionTools = NULL; myCompoundSet.clear(); myIs2D = ( theHypType.endsWith("2D")); + myIs3D = (theHypType.endsWith("3D")); } GMSHPluginGUI_HypothesisCreator::~GMSHPluginGUI_HypothesisCreator() @@ -161,23 +162,27 @@ QFrame* GMSHPluginGUI_HypothesisCreator::buildFrame() row++; } - aGroupLayout->addWidget( new QLabel( tr( "GMSH_2D_ALGO" ), GroupC1 ), row, 0 ); - my2DAlgo = new QComboBox( GroupC1 ); - QStringList types2DAlgo; - types2DAlgo << tr( "GMSH_AUTOMATIC" ) - << tr( "GMSH_MESH_ADAPT" ) - << tr( "GMSH_DELAUNAY" ) - << tr( "GMSH_FRONTAL" ) - << tr( "GMSH_DELAUNAY_FOR_QUAD" ) + my2DAlgo = 0; + if (!myIs3D) + { + aGroupLayout->addWidget(new QLabel(tr("GMSH_2D_ALGO"), GroupC1), row, 0); + my2DAlgo = new QComboBox(GroupC1); + QStringList types2DAlgo; + types2DAlgo << tr("GMSH_AUTOMATIC") + << tr("GMSH_MESH_ADAPT") + << tr("GMSH_DELAUNAY") + << tr("GMSH_FRONTAL") + << tr("GMSH_DELAUNAY_FOR_QUAD") #if GMSH_MAJOR_VERSION >=4 && GMSH_MINOR_VERSION >=10 - << tr( "GMSH_PACKING_OF_PARALLELOGRAMS" ) - << tr( "GMSH_QUASI_STRUCTURED_QUAD" ); + << tr("GMSH_PACKING_OF_PARALLELOGRAMS") + << tr("GMSH_QUASI_STRUCTURED_QUAD"); #else - << tr( "GMSH_PACKING_OF_PARALLELOGRAMS" ); + << tr("GMSH_PACKING_OF_PARALLELOGRAMS"); #endif - my2DAlgo->addItems( types2DAlgo ); - aGroupLayout->addWidget( my2DAlgo, row, 1 ); - row++; + my2DAlgo->addItems(types2DAlgo); + aGroupLayout->addWidget(my2DAlgo, row, 1); + row++; + } my3DAlgo = 0; if ( !myIs2D ) @@ -192,45 +197,55 @@ QFrame* GMSHPluginGUI_HypothesisCreator::buildFrame() row++; } - aGroupLayout->addWidget( new QLabel( tr( "GMSH_2D_RECOMB_ALGO" ), GroupC1 ), row, 0 ); - myRecomb2DAlgo = new QComboBox( GroupC1 ); - QStringList typesRecomb2DAlgo; + myRecomb2DAlgo = 0; + if (!myIs3D) + { + aGroupLayout->addWidget(new QLabel(tr("GMSH_2D_RECOMB_ALGO"), GroupC1), row, 0); + myRecomb2DAlgo = new QComboBox(GroupC1); + QStringList typesRecomb2DAlgo; #if GMSH_MAJOR_VERSION >=4 && GMSH_MINOR_VERSION >=8 - typesRecomb2DAlgo << tr( "GMSH_SIMPLE" ) << tr( "GMSH_BLOSSOM" ) << tr( "GMSH_SIMPLE_FULL_QUADS" ) << tr( "GMSH_BLOSSOM_FULL_QUADS" ); + typesRecomb2DAlgo << tr("GMSH_SIMPLE") << tr("GMSH_BLOSSOM") << tr("GMSH_SIMPLE_FULL_QUADS") << tr("GMSH_BLOSSOM_FULL_QUADS"); #else - typesRecomb2DAlgo << tr( "GMSH_STANDARD" ) << tr( "GMSH_BLOSSOM" ); + typesRecomb2DAlgo << tr("GMSH_STANDARD") << tr("GMSH_BLOSSOM"); #endif - myRecomb2DAlgo->addItems( typesRecomb2DAlgo ); - aGroupLayout->addWidget( myRecomb2DAlgo, row, 1 ); - row++; - + 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 ); + mySubdivAlgo = 0; + + aGroupLayout->addWidget(new QLabel(tr("GMSH_SUBDIV_ALGO"), GroupC1), row, 0); + mySubdivAlgo = new QComboBox(GroupC1); QStringList typesSubdivAlgo; - typesSubdivAlgo << tr( "GMSH_NONE" ) << tr( "GMSH_ALL_QUADS" ) << tr( "GMSH_ALL_HEXAS" ); - mySubdivAlgo->addItems( typesSubdivAlgo ); - aGroupLayout->addWidget( mySubdivAlgo, row, 1 ); + typesSubdivAlgo << tr("GMSH_NONE") << tr("GMSH_ALL_QUADS") << tr("GMSH_ALL_HEXAS"); + 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; - typesRemeshAlgo << tr( "GMSH_NO_SPLIT" ) << tr( "GMSH_AUTO" ) << tr( "GMSH_AUTO_ONLY_WITH_METIS" ); - myRemeshAlgo->addItems( typesRemeshAlgo ); - aGroupLayout->addWidget( myRemeshAlgo, row, 1 ); - row++; + myRemeshAlgo = 0; + myRemeshPara = 0; + if (!myIs3D) + { + aGroupLayout->addWidget(new QLabel(tr("GMSH_REMESH_ALGO"), GroupC1), row, 0); + myRemeshAlgo = new QComboBox(GroupC1); + QStringList typesRemeshAlgo; + typesRemeshAlgo << tr("GMSH_NO_SPLIT") << tr("GMSH_AUTO") << tr("GMSH_AUTO_ONLY_WITH_METIS"); + 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; - typesRemeshPara << tr( "GMSH_HARMONIC" ) << tr( "GMSH_CONFORMAL" ) << tr( "GMSH_RBF_HARMONIC" ); - myRemeshPara->addItems( typesRemeshPara ); - aGroupLayout->addWidget( myRemeshPara, row, 1 ); - row++; + aGroupLayout->addWidget(new QLabel(tr("GMSH_REMESH_PARA"), GroupC1), row, 0); + myRemeshPara = new QComboBox(GroupC1); + QStringList typesRemeshPara; + typesRemeshPara << tr("GMSH_HARMONIC") << tr("GMSH_CONFORMAL") << tr("GMSH_RBF_HARMONIC"); + 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 ); @@ -274,36 +289,38 @@ QFrame* GMSHPluginGUI_HypothesisCreator::buildFrame() 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); - myCompoundTable->horizontalHeader()->hideSection(0); - myCompoundTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); - 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); + if (!myIs3D) + { + 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); + myCompoundTable->horizontalHeader()->hideSection(0); + myCompoundTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + myCompoundTable->resizeColumnToContents(1); + myCompoundTable->setAlternatingRowColors(true); + myCompoundTable->verticalHeader()->hide(); - line2->setFrameShape(QFrame::HLine); - line2->setFrameShadow(QFrame::Sunken); - compoundLayout->addWidget(line2, 2, 1, 1, 1); + QPushButton* addCompoundButton = new QPushButton(tr("GMSH_COMPOUND_ADD"), compoundGroup); + compoundLayout->addWidget(addCompoundButton, 1, 1, 1, 1); + QFrame *line2 = new QFrame(compoundGroup); - QPushButton* removeButton = new QPushButton(tr("GMSH_COMPOUND_REMOVE"), compoundGroup); - compoundLayout->addWidget(removeButton, 3, 1, 1, 1); + line2->setFrameShape(QFrame::HLine); + line2->setFrameShadow(QFrame::Sunken); + compoundLayout->addWidget(line2, 2, 1, 1, 1); - connect( addCompoundButton, SIGNAL(clicked()), this, SLOT(onAddCompound())); - connect( removeButton, SIGNAL(clicked()), this, SLOT(onRemoveCompound())); + 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; } @@ -385,16 +402,21 @@ void GMSHPluginGUI_HypothesisCreator::retrieveParams() const if( myName ) myName->setText( data.myName ); - my2DAlgo->setCurrentIndex( data.my2DAlgo ); + if (!myIs3D) + my2DAlgo->setCurrentIndex( data.my2DAlgo ); if ( !myIs2D ) my3DAlgo->setCurrentIndex( data.my3DAlgo ); - myRecomb2DAlgo->setCurrentIndex( data.myRecomb2DAlgo ); + if(!myIs3D) + myRecomb2DAlgo->setCurrentIndex( data.myRecomb2DAlgo ); if ( myRecombineAll ) myRecombineAll->setChecked( data.myRecombineAll ); if ( mySubdivAlgo ) mySubdivAlgo->setCurrentIndex( data.mySubdivAlgo ); - myRemeshAlgo->setCurrentIndex( data.myRemeshAlgo); - myRemeshPara->setCurrentIndex( data.myRemeshPara); + if (!myIs3D) + { + myRemeshAlgo->setCurrentIndex(data.myRemeshAlgo); + myRemeshPara->setCurrentIndex(data.myRemeshPara); + } if(data.mySmouthStepsVar.isEmpty()) mySmouthSteps->setValue( data.mySmouthSteps ); else @@ -425,19 +447,22 @@ void GMSHPluginGUI_HypothesisCreator::retrieveParams() const GMSHPluginGUI_HypothesisCreator* that = (GMSHPluginGUI_HypothesisCreator*)this; that->updateWidgets(); - GeomSelectionTools* geomSelectionTools = that->getGeomSelectionTools(); - for (QSet::const_iterator i = myCompoundSet.begin(); i != myCompoundSet.end(); ++i) + if (!myIs3D) { - const QString entry = *i; - std::string shapeName = geomSelectionTools->getNameFromEntry(entry.toStdString()); - int row = myCompoundTable->rowCount(); - myCompoundTable->setRowCount(row+1); - myCompoundTable->setItem(row, 0, new QTableWidgetItem(entry)); - myCompoundTable->item(row, 0)->setFlags(0); - myCompoundTable->setItem(row, 1, new QTableWidgetItem(QString::fromStdString(shapeName))); - myCompoundTable->item(row, 1)->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); + GeomSelectionTools* geomSelectionTools = that->getGeomSelectionTools(); + for (QSet::const_iterator i = myCompoundSet.begin(); i != myCompoundSet.end(); ++i) + { + const QString entry = *i; + std::string shapeName = geomSelectionTools->getNameFromEntry(entry.toStdString()); + int row = myCompoundTable->rowCount(); + myCompoundTable->setRowCount(row + 1); + myCompoundTable->setItem(row, 0, new QTableWidgetItem(entry)); + myCompoundTable->item(row, 0)->setFlags(0); + myCompoundTable->setItem(row, 1, new QTableWidgetItem(QString::fromStdString(shapeName))); + myCompoundTable->item(row, 1)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + } + myCompoundTable->resizeColumnToContents(1); } - myCompoundTable->resizeColumnToContents(1); } QString GMSHPluginGUI_HypothesisCreator::storeParams() const @@ -509,15 +534,19 @@ bool GMSHPluginGUI_HypothesisCreator::storeParamsToHypo( const GmshHypothesisDat { if( isCreation() ) SMESH::SetName( SMESH::FindSObject( h ), h_data.myName.toLatin1().data() ); - - h->Set2DAlgo( h_data.my2DAlgo ); + if( !myIs3D ) + h->Set2DAlgo( h_data.my2DAlgo ); if ( !myIs2D ) h->Set3DAlgo( h_data.my3DAlgo ); - h->SetRecomb2DAlgo( h_data.myRecomb2DAlgo ); + if (!myIs3D) + h->SetRecomb2DAlgo( h_data.myRecomb2DAlgo ); h->SetRecombineAll( h_data.myRecombineAll ); h->SetSubdivAlgo( h_data.mySubdivAlgo ); - h->SetRemeshAlgo( h_data.myRemeshAlgo ); - h->SetRemeshPara( h_data.myRemeshPara ); + if (!myIs3D) + { + h->SetRemeshAlgo(h_data.myRemeshAlgo); + h->SetRemeshPara(h_data.myRemeshPara); + } h->SetSmouthSteps( h_data.mySmouthSteps ); h->SetSizeFactor( h_data.mySizeFactor ); #if GMSH_MAJOR_VERSION >=4 && GMSH_MINOR_VERSION >=10 @@ -567,14 +596,18 @@ bool GMSHPluginGUI_HypothesisCreator::storeParamsToHypo( const GmshHypothesisDat bool GMSHPluginGUI_HypothesisCreator::readParamsFromWidgets( GmshHypothesisData& h_data ) const { h_data.myName = myName ? myName->text() : ""; - h_data.my2DAlgo = my2DAlgo->currentIndex(); + if(my2DAlgo) + h_data.my2DAlgo = my2DAlgo->currentIndex(); if (my3DAlgo) h_data.my3DAlgo = my3DAlgo->currentIndex(); - h_data.myRecomb2DAlgo = myRecomb2DAlgo->currentIndex(); + if(myRecomb2DAlgo) + h_data.myRecomb2DAlgo = myRecomb2DAlgo->currentIndex(); h_data.myRecombineAll = myRecombineAll->isChecked(); h_data.mySubdivAlgo = mySubdivAlgo->currentIndex(); - h_data.myRemeshAlgo = myRemeshAlgo->currentIndex(); - h_data.myRemeshPara = myRemeshPara->currentIndex(); + if(myRemeshAlgo) + h_data.myRemeshAlgo = myRemeshAlgo->currentIndex(); + if(myRemeshPara) + h_data.myRemeshPara = myRemeshPara->currentIndex(); h_data.mySmouthSteps = mySmouthSteps->value(); h_data.mySizeFactor = mySizeFactor->value(); #if GMSH_MAJOR_VERSION >=4 && GMSH_MINOR_VERSION >=10 diff --git a/src/GUI/GMSHPluginGUI_HypothesisCreator.h b/src/GUI/GMSHPluginGUI_HypothesisCreator.h index 2b022c9..f0e6bdd 100644 --- a/src/GUI/GMSHPluginGUI_HypothesisCreator.h +++ b/src/GUI/GMSHPluginGUI_HypothesisCreator.h @@ -108,7 +108,7 @@ private: QCheckBox* myUseIncomplElem; QCheckBox* mySecondOrder; bool myIs2D; - + bool myIs3D; QTableWidget* myCompoundTable; GeomSelectionTools* myGeomSelectionTools; diff --git a/tests/gmsh_compound_mesh_1d_2d_3d.py b/tests/gmsh_compound_mesh_1d_2d_3d.py new file mode 100644 index 0000000..6291de2 --- /dev/null +++ b/tests/gmsh_compound_mesh_1d_2d_3d.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python + +''' +This file creates a compound solid of cube and a sphere. Then meshes them with +Gmsh using compound mesh feature of Gmsh. +''' +import salome +salome.salome_init() + +#------------------------------------- +### SHAPER component +#------------------------------------- + +from salome.shaper import model +model.begin() +partSet = model.moduleDocument() + +### Create Part +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() + +### Create Box +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) + +### Create Sphere +Sphere_1 = model.addSphere(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), 5) + +### Create Fuse +Fuse_1 = model.addFuse(Part_1_doc, [model.selection("COMPOUND", "all-in-Box_1"), model.selection("COMPOUND", "all-in-Sphere_1")], keepSubResults = True) + +### Create Group +Group_1_objects = [model.selection("FACE", "Box_1_1/Front"), + model.selection("FACE", "Box_1_1/Top"), + model.selection("FACE", "Fuse_1_1/Modified_Face&Box_1_1/Left"), + model.selection("FACE", "Box_1_1/Right"), + model.selection("FACE", "Fuse_1_1/Modified_Face&Box_1_1/Back"), + model.selection("FACE", "Fuse_1_1/Modified_Face&Box_1_1/Bottom")] +Group_1 = model.addGroup(Part_1_doc, "Faces", Group_1_objects) + +model.end() + +#------------------------------------- +### SHAPERSTUDY component +#------------------------------------- + +model.publishToShaperStudy() +import SHAPERSTUDY +Fuse_1_1, Group_1_1, = SHAPERSTUDY.shape(model.featureStringId(Fuse_1)) + + +#------------------------------------- +### SMESH component +#------------------------------------- + +import SMESH, SALOMEDS +from salome.smesh import smeshBuilder + +smesh = smeshBuilder.New() + +Mesh_1 = smesh.Mesh(Fuse_1_1) +GMSH = Mesh_1.Tetrahedron(algo=smeshBuilder.GMSH) +Gmsh_Parameters = GMSH.Parameters() +Gmsh_Parameters.Set2DAlgo( 0 ) +Gmsh_Parameters.SetMinSize( 0.5 ) +Gmsh_Parameters.SetMaxSize( 1 ) +Gmsh_Parameters.SetIs2d( 0 ) +Gmsh_Parameters.SetCompoundOnShape(Group_1_1) +Group_1_2 = Mesh_1.GroupOnGeom(Group_1_1,'Group_1',SMESH.FACE) +#isDone = Mesh_1.Compute() +#[ Group_1_2 ] = Mesh_1.GetGroups() + +errorMsg='' +okMsg='' + + +#------------------------------------- +# Test: Frontal Delaunay +#------------------------------------- +try: + isDone = Mesh_1.Compute() + if not isDone: + errorMsg+= '\n ERROR: failed to mesh the compound cube-sphere surface using Delaunay algorithm from Gmsh\n' + else: + okMsg+= '\n PASSED: Successfully meshed the compound cube-sphere surface using Delaunay algorithm from Gmsh\n' +except: + errorMsg+='\n ERROR: Exception raised in Mesh computation' + +#------------------------------------- +# Message that test are OK or not +#------------------------------------- + +if okMsg!= '': + print (okMsg) + +if errorMsg!= '': + raise RuntimeError (errorMsg + "\n Test is KO.") + + + +if salome.sg.hasDesktop(): + smesh.SetName(GMSH.GetAlgorithm(), 'GMSH') + smesh.SetName(Group_1_2, 'Group_1') + smesh.SetName(Mesh_1.GetMesh(), 'Mesh_1') + smesh.SetName(Gmsh_Parameters, 'Gmsh Parameters') + salome.sg.updateObjBrowser() diff --git a/tests/gmsh_compound_mesh_3d.py b/tests/gmsh_compound_mesh_3d.py index 6291de2..efcb306 100644 --- a/tests/gmsh_compound_mesh_3d.py +++ b/tests/gmsh_compound_mesh_3d.py @@ -58,7 +58,15 @@ from salome.smesh import smeshBuilder smesh = smeshBuilder.New() Mesh_1 = smesh.Mesh(Fuse_1_1) -GMSH = Mesh_1.Tetrahedron(algo=smeshBuilder.GMSH) +GMSH_2D = Mesh_1.Triangle(algo=smeshBuilder.GMSH_2D) +Gmsh_Parameters = GMSH_2D.Parameters() +Gmsh_Parameters.Set2DAlgo( 0 ) +Gmsh_Parameters.SetMaxSize( 10 ) +Gmsh_Parameters.SetMinSize( 5 ) +Gmsh_Parameters.SetIs2d( 1 ) +Gmsh_Parameters.SetCompoundOnShape(Group_1_1) +isDone = Mesh_1.Compute() +GMSH = Mesh_1.Tetrahedron(algo=smeshBuilder.GMSH_3D) Gmsh_Parameters = GMSH.Parameters() Gmsh_Parameters.Set2DAlgo( 0 ) Gmsh_Parameters.SetMinSize( 0.5 ) @@ -66,8 +74,6 @@ Gmsh_Parameters.SetMaxSize( 1 ) Gmsh_Parameters.SetIs2d( 0 ) Gmsh_Parameters.SetCompoundOnShape(Group_1_1) Group_1_2 = Mesh_1.GroupOnGeom(Group_1_1,'Group_1',SMESH.FACE) -#isDone = Mesh_1.Compute() -#[ Group_1_2 ] = Mesh_1.GetGroups() errorMsg='' okMsg='' diff --git a/tests/gmsh_mesh_3d.py b/tests/gmsh_mesh_3d.py new file mode 100644 index 0000000..b0964a2 --- /dev/null +++ b/tests/gmsh_mesh_3d.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python + +''' +This file creates a compound solid of cube and a sphere. Then meshes them with +Gmsh using compound mesh feature of Gmsh. +''' +import salome +salome.salome_init() + +#------------------------------------- +### SHAPER component +#------------------------------------- + +from salome.shaper import model +model.begin() +partSet = model.moduleDocument() + +### Create Part +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() + +### Create Box +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) + +### Create Sphere +Sphere_1 = model.addSphere(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), 5) + +### Create Fuse +Fuse_1 = model.addFuse(Part_1_doc, [model.selection("COMPOUND", "all-in-Box_1"), model.selection("COMPOUND", "all-in-Sphere_1")], keepSubResults = True) + +### Create Group +Group_1_objects = [model.selection("FACE", "Box_1_1/Front"), + model.selection("FACE", "Box_1_1/Top"), + model.selection("FACE", "Fuse_1_1/Modified_Face&Box_1_1/Left"), + model.selection("FACE", "Box_1_1/Right"), + model.selection("FACE", "Fuse_1_1/Modified_Face&Box_1_1/Back"), + model.selection("FACE", "Fuse_1_1/Modified_Face&Box_1_1/Bottom")] +Group_1 = model.addGroup(Part_1_doc, "Faces", Group_1_objects) + +model.end() + +#------------------------------------- +### SHAPERSTUDY component +#------------------------------------- + +model.publishToShaperStudy() +import SHAPERSTUDY +Fuse_1_1, Group_1_1, = SHAPERSTUDY.shape(model.featureStringId(Fuse_1)) + + +#------------------------------------- +### SMESH component +#------------------------------------- + +import SMESH, SALOMEDS +from salome.smesh import smeshBuilder + +smesh = smeshBuilder.New() + +Mesh_1 = smesh.Mesh(Fuse_1_1) +GMSH_2D = Mesh_1.Triangle(algo=smeshBuilder.GMSH_2D) +Gmsh_Parameters_2D = GMSH_2D.Parameters() +Gmsh_Parameters_2D.Set2DAlgo( 0 ) +Gmsh_Parameters_2D.SetMaxSize( 1 ) +Gmsh_Parameters_2D.SetMinSize( 0.5 ) +Gmsh_Parameters_2D.SetIs2d( 1 ) +isDone = Mesh_1.Compute() +GMSH = Mesh_1.Tetrahedron(algo=smeshBuilder.GMSH_3D) +Gmsh_Parameters_3D = GMSH.Parameters() +Gmsh_Parameters_3D.Set3DAlgo( 4 ) +Gmsh_Parameters_3D.SetMinSize( 0.5 ) +Gmsh_Parameters_3D.SetMaxSize( 1 ) +Gmsh_Parameters_3D.SetIs2d( 0 ) +Group_1_2 = Mesh_1.GroupOnGeom(Group_1_1,'Group_1',SMESH.FACE) + +errorMsg='' +okMsg='' + + +#------------------------------------- +# Test: Frontal Delaunay +#------------------------------------- +try: + isDone = Mesh_1.Compute() + if not isDone: + errorMsg+= '\n ERROR: failed to mesh the compound cube-sphere surface using Delaunay HXT algorithm from Gmsh\n' + else: + okMsg+= '\n PASSED: Successfully meshed the compound cube-sphere surface using Delaunay HXT algorithm from Gmsh\n' +except: + errorMsg+='\n ERROR: Exception raised in Mesh computation' + +#------------------------------------- +# Message that test are OK or not +#------------------------------------- + +if okMsg!= '': + print (okMsg) + +if errorMsg!= '': + raise RuntimeError (errorMsg + "\n Test is KO.") + +# Compare volumes +from GeomAlgoAPI import * +# is there a simpler way to get the volume of a shape? +shape_volume = GeomAlgoAPI_ShapeTools.volume(Fuse_1.results()[0].resultSubShapePair()[0].shape()) +mesh_volume = Mesh_1.GetVolume() +print("shape_volume: ", shape_volume) +print("mesh_volume: ", mesh_volume) + +assert abs(shape_volume - mesh_volume)/shape_volume < 0.01 + +if salome.sg.hasDesktop(): + smesh.SetName(GMSH.GetAlgorithm(), 'GMSH') + smesh.SetName(Group_1_2, 'Group_1') + smesh.SetName(Mesh_1.GetMesh(), 'Mesh_1') + smesh.SetName(Gmsh_Parameters_2D, 'Gmsh Parameters 2D') + smesh.SetName(Gmsh_Parameters_3D, 'Gmsh Parameters 3D') + salome.sg.updateObjBrowser() diff --git a/tests/tests.set b/tests/tests.set index bc66b5d..4a85e1a 100644 --- a/tests/tests.set +++ b/tests/tests.set @@ -25,8 +25,10 @@ SET(TUI_NAMES gmsh_triangulation_algorithms_for_square ) SET(GUI_NAMES + gmsh_compound_mesh_1d_2d_3d gmsh_compound_mesh_2d gmsh_compound_mesh_3d + gmsh_mesh_3d ) SET(TEST_NAMES ${TUI_NAMES} ${GUI_NAMES})