From: Yoann Audouin Date: Fri, 21 Oct 2022 13:03:25 +0000 (+0200) Subject: Adding parallel meshing (NETGEN only, Linux Only) X-Git-Tag: V9_10_0b1 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=c659eaa0eb1389e42ce1b31c37a89c61ed2163cd;p=modules%2Fsmesh.git Adding parallel meshing (NETGEN only, Linux Only) See example test/SMESH_ParallelCompute.py for an example --- diff --git a/doc/gui/input/about_meshes.rst b/doc/gui/input/about_meshes.rst index 73af1714e..619bd799f 100644 --- a/doc/gui/input/about_meshes.rst +++ b/doc/gui/input/about_meshes.rst @@ -52,7 +52,7 @@ The mesh can include the following entities: * **Node** - a mesh entity defining a position in 3D space with coordinates (x, y, z). * **Edge** (or segment) - 1D mesh element linking two nodes. * **Face** - 2D mesh element representing a part of surface bound by links between face nodes. A face can be a triangle, quadrangle or polygon. -* **Volume** - 3D mesh element representing a part of 3D space bound by volume facets. Nodes of a volume describing each facet are defined by the :ref:`connectivity convention `. A volume can be a tetrahedron, hexahedron, pentahedron, pyramid, hexagonal prism or polyhedron. +* **Volume** - 3D mesh element representing a part of 3D space bound by volume facets. Nodes of a volume describing each facet are defined by the :ref:`connectivity convention `. A volume can be a tetrahedron, hexahedron, pentahedron, pyramid, hexagonal or polyhedron. * **0D** element - mesh element defined by one node. * **Ball** element - discrete mesh element defined by a node and a diameter. diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index bfbb0cdd5..7b86361d8 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -156,7 +156,7 @@ module SMESH Geom_BALL, Geom_LAST }; - + /*! * ElementOrder points out entities of what order are requested */ @@ -238,7 +238,7 @@ module SMESH DRS_FAIL // general failure (exception etc.) }; - /*! + /*! * \brief A structure containing information about MED file */ struct MedFileInfo @@ -263,7 +263,7 @@ module SMESH */ const long EXTRUSION_FLAG_BOUNDARY = 1; const long EXTRUSION_FLAG_SEW = 2; - + /*! * Structure used in mesh edit preview data (MeshPreviewStruct) */ @@ -344,7 +344,7 @@ module SMESH /*! * Get geom shape to mesh. A result should not be nil. Use HasShapeToMesh() - * to know if a returned shape + * to know if a returned shape */ GEOM::GEOM_Object GetShapeToMesh() raises (SALOME::SALOME_Exception); @@ -457,7 +457,7 @@ module SMESH in SMESH_GroupBase aGroup2, in string name ) raises (SALOME::SALOME_Exception); - + /*! * Union of list of groups * New group is created. All mesh elements that are @@ -476,7 +476,7 @@ module SMESH in SMESH_GroupBase aGroup2, in string name ) raises (SALOME::SALOME_Exception); - + /*! * Intersection of list of groups * New group is created. All mesh elements that are @@ -495,7 +495,7 @@ module SMESH in SMESH_GroupBase aToolGroup, in string name ) raises (SALOME::SALOME_Exception); - + /*! * Cut of lists of groups * New group is created. All mesh elements that are present in @@ -505,14 +505,14 @@ module SMESH in ListOfGroups aToolGroups, in string name) raises (SALOME::SALOME_Exception); - + /*! * Create a group of entities basing on nodes of other groups. * \param [in] aListOfGroups - list of either groups, sub-meshes or filters. * \param [in] anElemType - a type of elements to include to the new group. * \param [in] name - a name of the new group. * \param [in] nbCommonNodes - criterion of inclusion of an element to the new group. - * \param [in] underlyingOnly - if \c True, an element is included to the + * \param [in] underlyingOnly - if \c True, an element is included to the * new group provided that it is based on nodes of an element of * \a aListOfGroups * \return SMESH_Group - the created group @@ -679,12 +679,12 @@ module SMESH * med files in 4.0.0 (default format) or 3.2.1 or 3.3.1 formats. * The minor must be between 0 and the current minor version of MED file library. * If version is equal to -1, the version is not changed (default). - * - autoDimension : if @c True, a space dimension for export is defined by mesh + * - autoDimension : if @c True, a space dimension for export is defined by mesh * configuration; for example a planar mesh lying on XOY plane - * will be exported as a mesh in 2D space. + * will be exported as a mesh in 2D space. * If @a autoDimension == @c False, the space dimension is 3. * - fields : list of GEOM fields defined on the shape to mesh. - * - geomAssocFields : each character of this string means a need to export a + * - geomAssocFields : each character of this string means a need to export a * corresponding field; correspondence between fields and characters is following: * - 'v' stands for _vertices_ field; * - 'e' stands for _edges_ field; @@ -724,7 +724,7 @@ module SMESH * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32) */ long_array GetMEDVersionsCompatibleForAppend(); - + /*! * Export Mesh to different Formats * (UNV supported version is I-DEAS 10) @@ -735,17 +735,17 @@ module SMESH in boolean renumer ) raises (SALOME::SALOME_Exception); void ExportSTL( in string file, in boolean isascii ) raises (SALOME::SALOME_Exception); - void ExportCGNS( in SMESH_IDSource meshPart, + void ExportCGNS( in SMESH_IDSource meshPart, in string file, in boolean overwrite, in boolean groupElemsByType) raises (SALOME::SALOME_Exception); - void ExportGMF( in SMESH_IDSource meshPart, + void ExportGMF( in SMESH_IDSource meshPart, in string file, in boolean withRequiredGroups) raises (SALOME::SALOME_Exception); - void ExportPartToDAT( in SMESH_IDSource meshPart, + void ExportPartToDAT( in SMESH_IDSource meshPart, in string file, in boolean renumer ) raises (SALOME::SALOME_Exception); - void ExportPartToUNV( in SMESH_IDSource meshPart, + void ExportPartToUNV( in SMESH_IDSource meshPart, in string file, in boolean renumer ) raises (SALOME::SALOME_Exception); void ExportPartToSTL( in SMESH_IDSource meshPart, @@ -857,10 +857,10 @@ module SMESH smIdType_array GetNodesId() raises (SALOME::SALOME_Exception); - + /*! * Returns type of mesh element - */ + */ ElementType GetElementType( in smIdType id, in boolean iselem ) raises (SALOME::SALOME_Exception); @@ -875,7 +875,7 @@ module SMESH smIdType_array GetSubMeshNodesId(in long ShapeID, in boolean all ) raises (SALOME::SALOME_Exception); - + ElementType GetSubMeshElementType(in long ShapeID) raises (SALOME::SALOME_Exception); @@ -899,6 +899,11 @@ module SMESH */ boolean SetMeshOrder(in submesh_array_array theSubMeshArray); + /*! + * \brief Set Number of Threads + */ + void SetNbThreads(in long nbThreads); + /*! /*! * Get mesh description @@ -939,7 +944,7 @@ module SMESH long GetShapeID(in smIdType id); /*! - * For given element returns ID of result shape after + * For given element returns ID of result shape after * ::FindShape() from SMESH_MeshEditor * If there is not element for given ID - returns -1 */ @@ -1072,7 +1077,7 @@ module SMESH */ smIdType_array GetElementsByType( in ElementType theType ) raises (SALOME::SALOME_Exception); - + /*! * Returns type of mesh element (same as SMESH_Mesh::GetElementType() ) */ diff --git a/src/SMESH/CMakeLists.txt b/src/SMESH/CMakeLists.txt index 7929c74f8..88d42d875 100644 --- a/src/SMESH/CMakeLists.txt +++ b/src/SMESH/CMakeLists.txt @@ -90,6 +90,9 @@ SET(SMESHimpl_HEADERS SMESH_SMESH.hxx MG_ADAPT.hxx SMESH_Homard.hxx + SMESH_DriverMesh.hxx + SMESH_DriverShape.hxx + SMESH_MeshLocker.hxx ) # --- sources --- @@ -110,6 +113,9 @@ SET(SMESHimpl_SOURCES SMESH_MesherHelper.cxx MG_ADAPT.cxx SMESH_Homard.cxx + SMESH_DriverMesh.cxx + SMESH_DriverShape.cxx + SMESH_MeshLocker.cxx ) # --- rules --- @@ -117,7 +123,7 @@ SET(SMESHimpl_SOURCES ADD_LIBRARY(SMESHimpl ${SMESHimpl_SOURCES}) IF(WIN32) TARGET_COMPILE_OPTIONS(SMESHimpl PRIVATE /bigobj) - ADD_DEFINITIONS(-DNOMINMAX) + ADD_DEFINITIONS(-DNOMINMAX) ENDIF(WIN32) TARGET_LINK_LIBRARIES(SMESHimpl ${_link_LIBRARIES} ) diff --git a/src/SMESH/SMESH_Algo.cxx b/src/SMESH/SMESH_Algo.cxx index 788a048c1..582e554ee 100644 --- a/src/SMESH/SMESH_Algo.cxx +++ b/src/SMESH/SMESH_Algo.cxx @@ -169,7 +169,7 @@ const SMESH_Algo::Features& SMESH_Algo::GetFeatures( const std::string& algoType //============================================================================= /*! - * + * */ //============================================================================= @@ -186,7 +186,7 @@ SMESH_Algo::SMESH_Algo (int hypId, SMESH_Gen * gen) //============================================================================= /*! - * + * */ //============================================================================= @@ -198,7 +198,7 @@ SMESH_Algo::~SMESH_Algo() //============================================================================= /*! - * + * */ //============================================================================= @@ -238,7 +238,7 @@ istream & SMESH_Algo::LoadFrom(istream & load) { return load; } //============================================================================= /*! - * + * */ //============================================================================= @@ -252,7 +252,7 @@ const vector < string > &SMESH_Algo::GetCompatibleHypothesis() * List the hypothesis used by the algorithm associated to the shape. * Hypothesis associated to father shape -are- taken into account (see * GetAppliedHypothesis). Relevant hypothesis have a name (type) listed in - * the algorithm. This method could be surcharged by specific algorithms, in + * the algorithm. This method could be surcharged by specific algorithms, in * case of several hypothesis simultaneously applicable. */ //============================================================================= @@ -264,7 +264,7 @@ SMESH_Algo::GetUsedHypothesis(SMESH_Mesh & aMesh, { SMESH_Algo* me = const_cast< SMESH_Algo* >( this ); - std::list savedHyps; // don't delete the list if + std::list savedHyps; // don't delete the list if savedHyps.swap( me->_usedHypList ); // it does not change (#16578) me->_usedHypList.clear(); @@ -565,7 +565,7 @@ bool SMESH_Algo::IsStraight( const TopoDS_Edge & E, return false; // E seems closed double edgeTol = 10 * curve.Tolerance(); - double lenTol2 = lineLen2 * 1e-4; + double lenTol2 = lineLen2 * 1e-4; double tol2 = Min( edgeTol * edgeTol, lenTol2 ); const double nbSamples = 7; @@ -816,7 +816,7 @@ SMESH_Algo::EMeshError SMESH_Algo::GetMeshError(SMESH_subMesh* subMesh) /*! * \brief Sets event listener to submeshes if necessary * \param subMesh - submesh where algo is set - * + * * After being set, event listener is notified on each event of a submesh. * By default non listener is set */ @@ -1020,7 +1020,7 @@ void SMESH_Algo::addBadInputElements(const SMESHDS_SubMesh* sm, //============================================================================= /*! - * + * */ //============================================================================= @@ -1034,7 +1034,7 @@ void SMESH_Algo::addBadInputElements(const SMESHDS_SubMesh* sm, //============================================================================= /*! - * + * */ //============================================================================= diff --git a/src/SMESH/SMESH_Algo.hxx b/src/SMESH/SMESH_Algo.hxx index 3beb89ae1..580d73d68 100644 --- a/src/SMESH/SMESH_Algo.hxx +++ b/src/SMESH/SMESH_Algo.hxx @@ -198,15 +198,15 @@ class SMESH_EXPORT SMESH_Algo : public SMESH_Hypothesis /*! * \brief Return a list of compatible hypotheses used to mesh a shape - * \param aMesh - the mesh + * \param aMesh - the mesh * \param aShape - the shape * \param ignoreAuxiliary - do not include auxiliary hypotheses in the list * \retval const std::list - hypotheses list - * + * * List the hypothesis used by the algorithm associated to the shape. * Hypothesis associated to father shape -are- taken into account (see * GetAppliedHypothesis). Relevant hypothesis have a name (type) listed in - * the algorithm. This method could be surcharged by specific algorithms, in + * the algorithm. This method could be surcharged by specific algorithms, in * case of several hypothesis simultaneously applicable. */ virtual const std::list & @@ -277,10 +277,13 @@ public: // 6 - if algo !NeedDiscreteBoundary() but requires presence of // hypotheses of dimension to generate all-dimensional mesh. // This info is used not to issue warnings on hiding of lower global algos. + // + + virtual void setSubMeshesToCompute(SMESH_subMesh * aSubMesh) {SubMeshesToCompute().assign( 1, aSubMesh );} public: // ================================================================== - // Methods to track non hierarchical dependencies between submeshes + // Methods to track non hierarchical dependencies between submeshes // ================================================================== /*! @@ -292,7 +295,7 @@ public: * By default none listener is set */ virtual void SetEventListener(SMESH_subMesh* subMesh); - + /*! * \brief Allow algo to do something after persistent restoration * \param subMesh - restored submesh @@ -300,7 +303,7 @@ public: * This method is called only if a submesh has HYP_OK algo_state. */ virtual void SubmeshRestored(SMESH_subMesh* subMesh); - + public: // ================================================================== // Common algo utilities @@ -398,7 +401,7 @@ public: enum EMeshError { MEr_OK = 0, MEr_HOLES, MEr_BAD_ORI, MEr_EMPTY }; /*! - * \brief Finds topological errors of a sub-mesh + * \brief Finds topological errors of a sub-mesh */ static EMeshError GetMeshError(SMESH_subMesh* subMesh); @@ -434,7 +437,7 @@ protected: std::vector _compatibleHypothesis; std::list _usedHypList; std::list _assigedShapeList; // _usedHypList assigned to - + // Algo features influencing which Compute() and how is called: // in what turn and with what input shape. diff --git a/src/SMESH/SMESH_DriverMesh.cxx b/src/SMESH/SMESH_DriverMesh.cxx new file mode 100644 index 000000000..60450141b --- /dev/null +++ b/src/SMESH/SMESH_DriverMesh.cxx @@ -0,0 +1,105 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESH_DriverMesh.cxx +// Author : Yoann AUDOUIN, EDF +// Module : SMESH +// + +#include "utilities.h" + +#include "SMESH_DriverMesh.hxx" + +#include "SMESH_Mesh.hxx" +#include "SMESH_Gen.hxx" + +#include +#include + +using namespace MEDCoupling; + +/** + * @brief Compares the mesh from two mesh files (MED) + * + * @param mesh_file1 First file + * @param mesh_file2 Second file + * @param mesh_name Name of the mesh in the files + * + * @return true if the mesh within the files are identical + */ +bool SMESH_DriverMesh::diffMEDFile(const std::string mesh_file1, const std::string mesh_file2, const std::string mesh_name){ + MEDFileUMesh* medmesh1 = MEDFileUMesh::New(mesh_file1, mesh_name); + MEDFileUMesh* medmesh2 = MEDFileUMesh::New(mesh_file2, mesh_name); + MEDCouplingUMesh *m0_1=medmesh1->getMeshAtLevel(0,false); + MEDCouplingUMesh *m0_2=medmesh2->getMeshAtLevel(0,false); + return m0_1->isEqual(m0_2, 1e-12); +} + +std::string getMeshName(std::string mesh_file){ + // TODO: Memory leak but desctructor private check with AG + MEDFileUMesh * myMedMesh = MEDFileUMesh::New(mesh_file); + + return myMedMesh->getLevel0Mesh()->getName(); +} + +/** + * @brief Import a mesh from a mesh file (MED) into a SMESH_Mesh object + * + * @param mesh_file the file + * @param aMesh the object + * @param mesh_name the name of the mesh in the file + * + * @return error code + */ +int SMESH_DriverMesh::importMesh(const std::string mesh_file, SMESH_Mesh& aMesh){ + // TODO: change that as it depends on the language + std::string mesh_name = getMeshName(mesh_file); + MESSAGE("Importing mesh from " << mesh_file << " mesh " << mesh_name); + int ret = aMesh.MEDToMesh(mesh_file.c_str(), mesh_name.c_str()); + return ret; +} + +/** + * @brief Export the content of a SMESH_Mesh into a mesh file (MED) + * + * @param mesh_file the file + * @param aMesh the object + * @param mesh_name name of the mesh in the file + * + * @return error code + */ + +int SMESH_DriverMesh::exportMesh(const std::string mesh_file, SMESH_Mesh& aMesh, const std::string mesh_name){ + + MESSAGE("Exporting mesh to " << mesh_file); + aMesh.ExportMED(mesh_file.c_str(), // theFile + mesh_name.c_str(), // theMeshName + false, // theAutoGroups + -1, // theVersion + nullptr, // theMeshPart + true, // theAutoDimension + true, // theAddODOnVertices + 1e-8, // theZTolerance + true // theSaveNumbers + ); + return true; +} diff --git a/src/SMESH/SMESH_DriverMesh.hxx b/src/SMESH/SMESH_DriverMesh.hxx new file mode 100644 index 000000000..83485aa8a --- /dev/null +++ b/src/SMESH/SMESH_DriverMesh.hxx @@ -0,0 +1,47 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESH_DriverMesh.hxx +// Author : Yoann AUDOUIN, EDF +// Module : SMESH +// + +#ifndef _SMESH_DRIVERMESH_HXX_ +#define _SMESH_DRIVERMESH_HXX_ + +#include +#include +#include "SMESH_SMESH.hxx" + +class SMESH_Mesh; +class SMESH_EXPORT SMESH_DriverMesh{ + public: + static bool diffMEDFile(const std::string mesh_file1, + const std::string mesh_file2, + const std::string mesh_name); + static int importMesh(const std::string mesh_file, + SMESH_Mesh& aMesh); + static int exportMesh(const std::string mesh_file, + SMESH_Mesh& aMesh, + const std::string meshName); +}; +#endif diff --git a/src/SMESH/SMESH_DriverShape.cxx b/src/SMESH/SMESH_DriverShape.cxx new file mode 100644 index 000000000..8efa1943f --- /dev/null +++ b/src/SMESH/SMESH_DriverShape.cxx @@ -0,0 +1,188 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESH_DriverShape.cxx +// Author : Yoann AUDOUIN, EDF +// Module : SMESH +// +#include +#include +#include "SMESH_DriverShape.hxx" + +// step include +#include +#include +#include + +// Brep include +#include +#include + +//Occ include +#include + +#ifndef WIN32 +#include +#include +namespace fs = boost::filesystem; +#endif + +/** + * @brief Import the content of a shape file (STEP) into a TopDS_Shape object + * + * @param shape_file the shape file + * @param aShape the object + * + * @return error code + */ +int importSTEPShape(const std::string shape_file, TopoDS_Shape& aShape){ + + MESSAGE("Importing STEP shape from " << shape_file); + STEPControl_Reader reader; + // Forcing Unit in meter + Interface_Static::SetCVal("xstep.cascade.unit","M"); + Interface_Static::SetIVal("read.step.ideas", 1); + Interface_Static::SetIVal("read.step.nonmanifold", 1); + IFSelect_ReturnStatus aStat = reader.ReadFile(shape_file.c_str()); + if(aStat != IFSelect_RetDone){ + throw SALOME_Exception("Reading error for " + shape_file); + } + + int NbTrans = reader.TransferRoots(); + // There should be only one shape within the file + assert(NbTrans==1); + aShape = reader.OneShape(); + + return false; +} + +/** + * @brief Export the content of a TopoDS_Shape into a shape file (STEP) + * + * @param shape_file the shape file + * @param aShape the object + * + * @return error code + */ +int exportSTEPShape(const std::string shape_file, const TopoDS_Shape& aShape){ + + MESSAGE("Exporting STEP shape to " << shape_file); + + STEPControl_Writer aWriter; + // Forcing Unit in meter + Interface_Static::SetCVal("xstep.cascade.unit","M"); + Interface_Static::SetCVal("write.step.unit","M"); + Interface_Static::SetIVal("write.step.nonmanifold", 1); + + IFSelect_ReturnStatus aStat = aWriter.Transfer(aShape,STEPControl_AsIs); + if(aStat != IFSelect_RetDone){ + throw SALOME_Exception("Reading error for " + shape_file); + } + + aStat = aWriter.Write(shape_file.c_str()); + + if(aStat != IFSelect_RetDone){ + throw SALOME_Exception("Writing error for " + shape_file); + } + return aStat; +} + +/** + * @brief Import the content of a shape file (BREP) into a TopDS_Shape object + * + * @param shape_file the shape file + * @param aShape the object + * + * @return error code + */ +int importBREPShape(const std::string shape_file, TopoDS_Shape& aShape){ + + MESSAGE("Importing BREP shape from " << shape_file); + BRep_Builder builder; + BRepTools::Read(aShape, shape_file.c_str(), builder); + + return false; +} + +/** + * @brief Export the content of a TopoDS_Shape into a shape file (BREP) + * + * @param shape_file the shape file + * @param aShape the object + * + * @return error code + */ +int exportBREPShape(const std::string shape_file, const TopoDS_Shape& aShape){ + + MESSAGE("Exporting BREP shape to " << shape_file); + BRepTools::Write(aShape, shape_file.c_str()); + + return false; +} + +/** + * @brief Import the content of a shape file into a TopDS_Shape object + * + * @param shape_file the shape file + * @param aShape the object + * + * @return error code + */ +int SMESH_DriverShape::importShape(const std::string shape_file, TopoDS_Shape& aShape){ +#ifndef WIN32 + std::string type = fs::path(shape_file).extension().string(); + boost::algorithm::to_lower(type); + if (type == ".brep"){ + return importBREPShape(shape_file, aShape); + } else if (type == ".step"){ + return importSTEPShape(shape_file, aShape); + } else { + throw SALOME_Exception("Unknow format for importShape: " + type); + } +#else + return 0; +#endif +} + +/** + * @brief Import the content of a shape file into a TopDS_Shape object + * + * @param shape_file the shape file + * @param aShape the object + * + * @return error code + */ +int SMESH_DriverShape::exportShape(const std::string shape_file, const TopoDS_Shape& aShape){ +#ifndef WIN32 + std::string type = fs::path(shape_file).extension().string(); + boost::algorithm::to_lower(type); + if (type == ".brep"){ + return exportBREPShape(shape_file, aShape); + } else if (type == ".step"){ + return exportSTEPShape(shape_file, aShape); + } else { + throw SALOME_Exception("Unknow format for exportShape: " + type); + } +#else + return 0; +#endif +} diff --git a/src/SMESH/SMESH_DriverShape.hxx b/src/SMESH/SMESH_DriverShape.hxx new file mode 100644 index 000000000..1d55b70a8 --- /dev/null +++ b/src/SMESH/SMESH_DriverShape.hxx @@ -0,0 +1,40 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESH_DriverShape.hxx +// Author : Yoann AUDOUIN, EDF +// Module : SMESH +// + +#ifndef _SMESH_DRIVERSHAPE_HXX_ +#define _SMESH_DRIVERSHAPE_HXX_ + +#include +#include +#include "SMESH_SMESH.hxx" +class TopoDS_Shape; +class SMESH_EXPORT SMESH_DriverShape{ + public: + static int importShape(const std::string shape_file, TopoDS_Shape& aShape); + static int exportShape(const std::string shape_file, const TopoDS_Shape& aShape); +}; +#endif diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index ef42e33e0..bd8098302 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -25,11 +25,14 @@ // Author : Paul RASCLE, EDF // Module : SMESH // - //#define CHRONODEF - +// +#ifndef WIN32 +#include +#endif #include "SMESH_Gen.hxx" +#include "SMESH_DriverMesh.hxx" #include "SMDS_Mesh.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" @@ -47,6 +50,7 @@ #include #include "memoire.h" +#include #ifdef WIN32 #include @@ -55,6 +59,10 @@ #include using namespace std; +#ifndef WIN32 +#include +namespace fs = boost::filesystem; +#endif // Environment variable separator #ifdef WIN32 @@ -155,6 +163,213 @@ SMESH_Mesh* SMESH_Gen::CreateMesh(bool theIsEmbeddedMode) return aMesh; } + +//============================================================================= +/*! + * Algo to run the computation of all the submeshes of a mesh in sequentila + */ +//============================================================================= + +bool SMESH_Gen::sequentialComputeSubMeshes( + SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + const ::MeshDimension aDim, + TSetOfInt* aShapesId /*=0*/, + TopTools_IndexedMapOfShape* allowedSubShapes, + SMESH_subMesh::compute_event &computeEvent, + const bool includeSelf, + const bool complexShapeFirst, + const bool aShapeOnly) +{ + MESSAGE("Compute submeshes sequentialy"); + + bool ret = true; + + SMESH_subMeshIteratorPtr smIt; + SMESH_subMesh *shapeSM = aMesh.GetSubMesh(aShape); + + smIt = shapeSM->getDependsOnIterator(includeSelf, !complexShapeFirst); + while ( smIt->more() ) + { + SMESH_subMesh* smToCompute = smIt->next(); + + // do not mesh vertices of a pseudo shape + const TopoDS_Shape& shape = smToCompute->GetSubShape(); + const TopAbs_ShapeEnum shapeType = shape.ShapeType(); + if ( !aMesh.HasShapeToMesh() && shapeType == TopAbs_VERTEX ) + continue; + + // check for preview dimension limitations + if ( aShapesId && GetShapeDim( shapeType ) > (int)aDim ) + { + // clear compute state not to show previous compute errors + // if preview invoked less dimension less than previous + smToCompute->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); + continue; + } + + if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) + { + if (_compute_canceled) + return false; + smToCompute->SetAllowedSubShapes( fillAllowed( shapeSM, aShapeOnly, allowedSubShapes )); + setCurrentSubMesh( smToCompute ); + smToCompute->ComputeStateEngine( computeEvent ); + setCurrentSubMesh( nullptr ); + smToCompute->SetAllowedSubShapes( nullptr ); + } + + // we check all the sub-meshes here and detect if any of them failed to compute + if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE && + ( shapeType != TopAbs_EDGE || !SMESH_Algo::isDegenerated( TopoDS::Edge( shape )))) + ret = false; + else if ( aShapesId ) + aShapesId->insert( smToCompute->GetId() ); + } + //aMesh.GetMeshDS()->Modified(); + return ret; + +}; + +//============================================================================= +/* + * compute of a submesh + * This function is passed to the thread pool + */ +//============================================================================= +const std::function + compute_function([] (SMESH_subMesh* sm, + SMESH_subMesh::compute_event event, + SMESH_subMesh *shapeSM, + bool aShapeOnly, + TopTools_IndexedMapOfShape *allowedSubShapes, + TSetOfInt* aShapesId) -> void +{ + if (sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) + { + sm->SetAllowedSubShapes( fillAllowed( shapeSM, aShapeOnly, allowedSubShapes )); + //setCurrentSubMesh( sm ); + sm->ComputeStateEngine(event); + //setCurrentSubMesh( nullptr ); + sm->SetAllowedSubShapes( nullptr ); + } + + if ( aShapesId ) + aShapesId->insert( sm->GetId() ); + +}); + +//============================================================================= +/*! + * Algo to run the computation of all the submeshes of a mesh in parallel + */ +//============================================================================= + +bool SMESH_Gen::parallelComputeSubMeshes( + SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + const ::MeshDimension aDim, + TSetOfInt* aShapesId /*=0*/, + TopTools_IndexedMapOfShape* allowedSubShapes, + SMESH_subMesh::compute_event &computeEvent, + const bool includeSelf, + const bool complexShapeFirst, + const bool aShapeOnly) +{ +#ifdef WIN32 + throw SALOME_Exception("ParallelMesh is not working on Windows"); +#else + + bool ret = true; + + SMESH_subMeshIteratorPtr smIt; + SMESH_subMesh *shapeSM = aMesh.GetSubMesh(aShape); + + // Pool of thread for computation + // TODO: move when parallelMesh created + aMesh.InitPoolThreads(); + aMesh.CreateTmpFolder(); + + TopAbs_ShapeEnum previousShapeType = TopAbs_VERTEX; + int nbThreads = aMesh.GetNbThreads(); + MESSAGE("Compute submeshes with threads: " << nbThreads); + + + smIt = shapeSM->getDependsOnIterator(includeSelf, !complexShapeFirst); + while ( smIt->more() ) + { + SMESH_subMesh* smToCompute = smIt->next(); + + // do not mesh vertices of a pseudo shape + const TopoDS_Shape& shape = smToCompute->GetSubShape(); + const TopAbs_ShapeEnum shapeType = shape.ShapeType(); + // Not doing in parallel 1D and 2D meshes + if ( !aMesh.HasShapeToMesh() && shapeType == TopAbs_VERTEX ) + continue; + if(shapeType==TopAbs_FACE||shapeType==TopAbs_EDGE) + aMesh.SetNbThreads(0); + else + aMesh.SetNbThreads(nbThreads); + + + if (shapeType != previousShapeType) { + // Waiting for all threads for the previous type to end + aMesh.wait(); + + std::string file_name; + switch(previousShapeType){ + case TopAbs_FACE: + file_name = "Mesh2D.med"; + break; + case TopAbs_EDGE: + file_name = "Mesh1D.med"; + break; + case TopAbs_VERTEX: + file_name = "Mesh0D.med"; + break; + case TopAbs_SOLID: + default: + file_name = ""; + break; + } + if(file_name != "") + { + fs::path mesh_file = fs::path(aMesh.tmp_folder) / fs::path(file_name); + SMESH_DriverMesh::exportMesh(mesh_file.string(), aMesh, "MESH"); + + } + //Resetting threaded pool info + previousShapeType = shapeType; + } + + // check for preview dimension limitations + if ( aShapesId && GetShapeDim( shapeType ) > (int)aDim ) + { + // clear compute state not to show previous compute errors + // if preview invoked less dimension less than previous + smToCompute->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); + continue; + } + boost::asio::post(*(aMesh._pool), std::bind(compute_function, smToCompute, computeEvent, + shapeSM, aShapeOnly, allowedSubShapes, + aShapesId)); + } + + // Waiting for the thread for Solids to finish + aMesh.wait(); + + aMesh.GetMeshDS()->Modified(); + aMesh.DeleteTmpFolder(); + + return ret; +#endif +}; + //============================================================================= /* * Compute a mesh @@ -201,57 +416,33 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, // =============================================== // Mesh all the sub-shapes starting from vertices // =============================================== + if (aMesh.IsParallel()) + ret = parallelComputeSubMeshes( + aMesh, aShape, aDim, + aShapesId, allowedSubShapes, + computeEvent, + includeSelf, + complexShapeFirst, + aShapeOnly); + else + ret = sequentialComputeSubMeshes( + aMesh, aShape, aDim, + aShapesId, allowedSubShapes, + computeEvent, + includeSelf, + complexShapeFirst, + aShapeOnly); - smIt = shapeSM->getDependsOnIterator(includeSelf, !complexShapeFirst); - while ( smIt->more() ) - { - SMESH_subMesh* smToCompute = smIt->next(); - - // do not mesh vertices of a pseudo shape - const TopoDS_Shape& shape = smToCompute->GetSubShape(); - const TopAbs_ShapeEnum shapeType = shape.ShapeType(); - if ( !aMesh.HasShapeToMesh() && shapeType == TopAbs_VERTEX ) - continue; - - // check for preview dimension limitations - if ( aShapesId && GetShapeDim( shapeType ) > (int)aDim ) - { - // clear compute state not to show previous compute errors - // if preview invoked less dimension less than previous - smToCompute->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); - continue; - } - - if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) - { - if (_compute_canceled) - return false; - smToCompute->SetAllowedSubShapes( fillAllowed( shapeSM, aShapeOnly, allowedSubShapes )); - setCurrentSubMesh( smToCompute ); - smToCompute->ComputeStateEngine( computeEvent ); - setCurrentSubMesh( nullptr ); - smToCompute->SetAllowedSubShapes( nullptr ); - } - - // we check all the sub-meshes here and detect if any of them failed to compute - if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE && - ( shapeType != TopAbs_EDGE || !SMESH_Algo::isDegenerated( TopoDS::Edge( shape )))) - ret = false; - else if ( aShapesId ) - aShapesId->insert( smToCompute->GetId() ); - } - //aMesh.GetMeshDS()->Modified(); return ret; } else { // ================================================================ - // Apply algos that do NOT require discreteized boundaries + // Apply algos that do NOT require discretized boundaries // ("all-dimensional") and do NOT support sub-meshes, starting from // the most complex shapes and collect sub-meshes with algos that // DO support sub-meshes // ================================================================ - list< SMESH_subMesh* > smWithAlgoSupportingSubmeshes[4]; // for each dim // map to sort sm with same dim algos according to dim of @@ -448,6 +639,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, sm->SetAllowedSubShapes( fillAllowed( shapeSM, aShapeOnly, allowedSubShapes )); setCurrentSubMesh( sm ); sm->ComputeStateEngine( computeEvent ); + setCurrentSubMesh( NULL ); sm->SetAllowedSubShapes( nullptr ); if ( aShapesId ) @@ -460,6 +652,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, // mesh the rest sub-shapes starting from vertices // ----------------------------------------------- ret = Compute( aMesh, aShape, aFlags | UPWARD, aDim, aShapesId, allowedSubShapes ); + } MEMOSTAT; @@ -603,7 +796,7 @@ bool SMESH_Gen::Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape& aSubShape = smToCompute->GetSubShape(); const int aShapeDim = GetShapeDim( aSubShape ); if ( aShapeDim < 1 ) break; - + SMESH_Algo* algo = GetAlgo( smToCompute ); if ( algo && !algo->NeedDiscreteBoundary() ) { if ( algo->SupportSubmeshes() ) { diff --git a/src/SMESH/SMESH_Gen.hxx b/src/SMESH/SMESH_Gen.hxx index b8b98a8a8..94058184e 100644 --- a/src/SMESH/SMESH_Gen.hxx +++ b/src/SMESH/SMESH_Gen.hxx @@ -34,6 +34,7 @@ #include "SMESH_Algo.hxx" #include "SMESH_ComputeError.hxx" +#include "SMESH_subMesh.hxx" #include #include @@ -41,6 +42,7 @@ #include #include + #include #include @@ -48,7 +50,7 @@ class SMESHDS_Document; class SMESH_Algo; class SMESH_Mesh; class TopoDS_Shape; -class SMESH_subMesh; + typedef SMESH_Hypothesis::Hypothesis_Status TAlgoStateErrorName; @@ -77,7 +79,7 @@ public: SHAPE_ONLY_UPWARD = 3 // SHAPE_ONLY | UPWARD }; /*! - * \brief Computes aMesh on aShape + * \brief Computes aMesh on aShape * \param aMesh - the mesh. * \param aShape - the shape. * \param aFlags - ComputeFlags. By default compute the whole mesh and compact at the end. @@ -101,7 +103,7 @@ public: const SMESH_subMesh* GetCurrentSubMesh() const; /*! - * \brief evaluates size of prospective mesh on a shape + * \brief evaluates size of prospective mesh on a shape * \param aMesh - the mesh * \param aShape - the shape * \param aResMap - map for prospective numbers of elements @@ -167,6 +169,28 @@ public: private: + + bool parallelComputeSubMeshes( + SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + const ::MeshDimension aDim, + TSetOfInt* aShapesId, + TopTools_IndexedMapOfShape* allowedSubShapes, + SMESH_subMesh::compute_event &computeEvent, + const bool includeSelf, + const bool complexShapeFirst, + const bool aShapeOnly); + + bool sequentialComputeSubMeshes( + SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + const ::MeshDimension aDim, + TSetOfInt* aShapesId /*=0*/, + TopTools_IndexedMapOfShape* allowedSubShapes, + SMESH_subMesh::compute_event &computeEvent, + const bool includeSelf, + const bool complexShapeFirst, + const bool aShapeOnly); int _localId; // unique Id of created objects, within SMESH_Gen entity StudyContextStruct* _studyContext; diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 90f4a8a02..0796cbd8a 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -80,6 +80,11 @@ #include #endif +#ifndef WIN32 +#include +namespace fs=boost::filesystem; +#endif + // maximum stored group name length in MED file #define MAX_MED_GROUP_NAME_LENGTH 80 @@ -162,13 +167,11 @@ namespace #ifndef WIN32 void deleteMeshDS(SMESHDS_Mesh* meshDS) { - //cout << "deleteMeshDS( " << meshDS << endl; delete meshDS; } #else static void* deleteMeshDS(void* meshDS) { - //cout << "deleteMeshDS( " << meshDS << endl; SMESHDS_Mesh* m = (SMESHDS_Mesh*)meshDS; if(m) { delete m; @@ -229,6 +232,8 @@ SMESH_Mesh::~SMESH_Mesh() int result=pthread_create(&thread, NULL, deleteMeshDS, (void*)_meshDS); #endif } + if(_pool) + DeletePoolThreads(); } //================================================================================ @@ -1756,7 +1761,6 @@ double SMESH_Mesh::GetComputeProgress() const rate = algo->GetProgressByTic(); computedCost += algoDoneCost + rate * algoNotDoneCost; } - // cout << "rate: "<GetMeshInfo().NbElements() << endl; return computedCost / totalCost; } @@ -2563,3 +2564,30 @@ void SMESH_Mesh::getAncestorsSubMeshes (const TopoDS_Shape& theSubSha // sort submeshes according to stored mesh order SortByMeshOrder( theSubMeshes ); } + + +//============================================================================= +/*! + * \brief Build folder for parallel computation + */ +//============================================================================= +void SMESH_Mesh::CreateTmpFolder() +{ +#ifndef WIN32 + // Temporary folder that will be used by parallel computation + tmp_folder = fs::temp_directory_path()/fs::unique_path(fs::path("SMESH_%%%%-%%%%")); + fs::create_directories(tmp_folder); +#endif +} +// +//============================================================================= +/*! + * \brief Delete temporary folder used for parallel computation + */ +//============================================================================= +void SMESH_Mesh::DeleteTmpFolder() +{ +#ifndef WIN32 + fs::remove_all(tmp_folder); +#endif +} diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index 461e949da..9c9606499 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -48,6 +48,12 @@ #include #include +#ifndef WIN32 +#include +#include +#endif +#include + #ifdef WIN32 #pragma warning(disable:4251) // Warning DLL Interface ... #pragma warning(disable:4290) // Warning Exception ... @@ -127,20 +133,20 @@ class SMESH_EXPORT SMESH_Mesh int UNVToMesh(const char* theFileName); int MEDToMesh(const char* theFileName, const char* theMeshName); - + std::string STLToMesh(const char* theFileName); int CGNSToMesh(const char* theFileName, const int theMeshIndex, std::string& theMeshName); - + SMESH_ComputeErrorPtr GMFToMesh(const char* theFileName, bool theMakeRequiredGroups = true ); SMESH_Hypothesis::Hypothesis_Status AddHypothesis(const TopoDS_Shape & aSubShape, int anHypId, std::string* error=0); - + SMESH_Hypothesis::Hypothesis_Status RemoveHypothesis(const TopoDS_Shape & aSubShape, int anHypId); - + const std::list & GetHypothesisList(const TopoDS_Shape & aSubShape) const; @@ -148,7 +154,7 @@ class SMESH_EXPORT SMESH_Mesh const SMESH_HypoFilter& aFilter, const bool andAncestors, TopoDS_Shape* assignedTo=0) const; - + int GetHypotheses(const TopoDS_Shape & aSubShape, const SMESH_HypoFilter& aFilter, std::list< const SMESHDS_Hypothesis * >& aHypList, @@ -159,7 +165,7 @@ class SMESH_EXPORT SMESH_Mesh const SMESH_HypoFilter& aFilter, const bool andAncestors, TopoDS_Shape* assignedTo=0) const; - + int GetHypotheses(const SMESH_subMesh * aSubMesh, const SMESH_HypoFilter& aFilter, std::list< const SMESHDS_Hypothesis * >& aHypList, @@ -169,25 +175,25 @@ class SMESH_EXPORT SMESH_Mesh SMESH_Hypothesis * GetHypothesis(const int aHypID) const; const std::list & GetLog(); - + void ClearLog(); - + int GetId() const { return _id; } - + bool MeshExists( int meshId ) const; - + SMESH_Mesh* FindMesh( int meshId ) const; SMESHDS_Mesh * GetMeshDS() { return _meshDS; } const SMESHDS_Mesh * GetMeshDS() const { return _meshDS; } - + SMESH_Gen *GetGen() { return _gen; } SMESH_subMesh *GetSubMesh(const TopoDS_Shape & aSubShape); - + SMESH_subMesh *GetSubMeshContaining(const TopoDS_Shape & aSubShape) const; - + SMESH_subMesh *GetSubMeshContaining(const int aShapeID) const; /*! * \brief Return submeshes of groups containing the given subshape @@ -209,7 +215,7 @@ class SMESH_EXPORT SMESH_Mesh * \brief check if a hypothesis allowing notconform mesh is present */ bool IsNotConformAllowed() const; - + bool IsMainShape(const TopoDS_Shape& theShape) const; TopoDS_Shape GetShapeByEntry(const std::string& entry) const; @@ -303,20 +309,20 @@ class SMESH_EXPORT SMESH_Mesh bool withRequiredGroups = true ); double GetComputeProgress() const; - + smIdType NbNodes() const; smIdType Nb0DElements() const; smIdType NbBalls() const; - + smIdType NbEdges(SMDSAbs_ElementOrder order = ORDER_ANY) const; - + smIdType NbFaces(SMDSAbs_ElementOrder order = ORDER_ANY) const; smIdType NbTriangles(SMDSAbs_ElementOrder order = ORDER_ANY) const; smIdType NbQuadrangles(SMDSAbs_ElementOrder order = ORDER_ANY) const; smIdType NbBiQuadQuadrangles() const; smIdType NbBiQuadTriangles() const; smIdType NbPolygons(SMDSAbs_ElementOrder order = ORDER_ANY) const; - + smIdType NbVolumes(SMDSAbs_ElementOrder order = ORDER_ANY) const; smIdType NbTetras(SMDSAbs_ElementOrder order = ORDER_ANY) const; smIdType NbHexas(SMDSAbs_ElementOrder order = ORDER_ANY) const; @@ -327,9 +333,9 @@ class SMESH_EXPORT SMESH_Mesh smIdType NbBiQuadPrisms() const; smIdType NbHexagonalPrisms() const; smIdType NbPolyhedrons() const; - + smIdType NbSubMesh() const; - + size_t NbGroup() const { return _mapGroup.size(); } int NbMeshes() const; // nb meshes in the Study @@ -344,9 +350,9 @@ class SMESH_EXPORT SMESH_Mesh typedef boost::shared_ptr< SMDS_Iterator > GroupIteratorPtr; GroupIteratorPtr GetGroups() const; - + std::list GetGroupIds() const; - + SMESH_Group* GetGroup (const int theGroupID) const; bool RemoveGroup (const int theGroupID); @@ -381,7 +387,49 @@ class SMESH_EXPORT SMESH_Mesh const SMESH_subMesh* smAfter ) const; std::ostream& Dump(std::ostream & save); - + + // Parallel computation functions + +#ifdef WIN32 + void Lock() {}; + void Unlock() {}; + + int GetNbThreads(){return _NbThreads;}; + void SetNbThreads(long nbThreads){std::cout << "Warning Parallel Meshing is disabled on Windows it will behave as a slower normal compute" << std::endl;_NbThreads=nbThreads;}; + + void InitPoolThreads(){}; + void DeletePoolThreads(){}; + void wait(){} + + bool IsParallel(){return _NbThreads > 0;} +#else + void Lock() {_my_lock.lock();}; + void Unlock() {_my_lock.unlock();}; + + int GetNbThreads(){return _NbThreads;}; + void SetNbThreads(long nbThreads){_NbThreads=nbThreads;}; + + void InitPoolThreads(){_pool = new boost::asio::thread_pool(_NbThreads);}; + void DeletePoolThreads(){delete _pool;}; + + void wait(){_pool->join(); DeletePoolThreads(); InitPoolThreads(); } + + bool IsParallel(){return _NbThreads > 0;} +#endif + + void CreateTmpFolder(); + void DeleteTmpFolder(); + + // Temporary folder used during parallel Computation +#ifndef WIN32 + boost::filesystem::path tmp_folder; + boost::asio::thread_pool * _pool = nullptr; //thread pool for computation +#else + std::string tmp_folder; + bool _pool = false; +#endif + + private: void exportMEDCommmon(DriverMED_W_SMESHDS_Mesh& myWriter, @@ -397,7 +445,7 @@ private: void fillAncestorsMap(const TopoDS_Shape& theShape); void getAncestorsSubMeshes(const TopoDS_Shape& theSubShape, std::vector< SMESH_subMesh* >& theSubMeshes) const; - + protected: int _id; // id given by creator (unique within the creator instance) int _groupId; // id generator for group objects @@ -410,12 +458,12 @@ protected: class SubMeshHolder; SubMeshHolder* _subMeshHolder; - + bool _isAutoColor; bool _isModified; //!< modified since last total re-compute, issue 0020693 double _shapeDiagonal; //!< diagonal size of bounding box of shape to mesh - + TopTools_IndexedDataMapOfShapeListOfShape _mapAncestors; mutable std::vector _ancestorSubMeshes; // to speed up GetHypothes[ei]s() @@ -428,9 +476,14 @@ protected: // 2) to forget not loaded mesh data at hyp modification TCallUp* _callUp; + // Mutex for multhitreading write in SMESH_Mesh +#ifndef WIN32 + boost::mutex _my_lock; +#endif + int _NbThreads=0; + protected: SMESH_Mesh(); SMESH_Mesh(const SMESH_Mesh&) {}; }; - #endif diff --git a/src/SMESH/SMESH_MeshLocker.cxx b/src/SMESH/SMESH_MeshLocker.cxx new file mode 100644 index 000000000..d04ce9248 --- /dev/null +++ b/src/SMESH/SMESH_MeshLocker.cxx @@ -0,0 +1,46 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESH_MeshLocker.cxx +// Author : Yoann AUDOUIN, EDF +// Module : SMESH +// + +#include "SMESH_MeshLocker.hxx" + +#include "SMESH_Mesh.hxx" + +/* + * When instanced will run the command Lock from a SMESH_Mesh + */ +SMESH_MeshLocker::SMESH_MeshLocker(SMESH_Mesh * aMesh) : _myMesh(aMesh) +{ + _myMesh->Lock(); +} + +/* + * When freed will run the command Unlock from the SMESH_Mesh associated + */ +SMESH_MeshLocker::~SMESH_MeshLocker() +{ + _myMesh->Unlock(); +} diff --git a/src/SMESH/SMESH_MeshLocker.hxx b/src/SMESH/SMESH_MeshLocker.hxx new file mode 100644 index 000000000..15b411909 --- /dev/null +++ b/src/SMESH/SMESH_MeshLocker.hxx @@ -0,0 +1,45 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESH_Mesh.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// +#ifndef _SMESH_MESHLOCKER_HXX_ +#define _SMESH_MESHLOCKER_HXX_ +#include "SMESH_SMESH.hxx" + +class SMESH_Mesh; + +class SMESH_EXPORT SMESH_MeshLocker{ +public: + SMESH_MeshLocker(SMESH_Mesh * aMesh); + ~SMESH_MeshLocker(); + +protected: + SMESH_MeshLocker(); + +private: + SMESH_Mesh * _myMesh=nullptr; +}; + +#endif diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index af658f2aa..b85c16f0d 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -28,7 +28,7 @@ #include "SMDS_EdgePosition.hxx" #include "SMDS_FaceOfNodes.hxx" -#include "SMDS_FacePosition.hxx" +#include "SMDS_FacePosition.hxx" #include "SMDS_IteratorOnIterators.hxx" #include "SMDS_VolumeTool.hxx" #include "SMESHDS_Mesh.hxx" @@ -100,7 +100,7 @@ SMESH_MesherHelper::SMESH_MesherHelper(SMESH_Mesh& theMesh) //======================================================================= //function : ~SMESH_MesherHelper -//purpose : +//purpose : //======================================================================= SMESH_MesherHelper::~SMESH_MesherHelper() @@ -425,7 +425,7 @@ bool SMESH_MesherHelper::GetNodeUVneedInFaceNode(const TopoDS_Face& F) const //======================================================================= //function : IsMedium -//purpose : +//purpose : //======================================================================= bool SMESH_MesherHelper::IsMedium(const SMDS_MeshNode* node, @@ -583,7 +583,7 @@ bool SMESH_MesherHelper::toCheckPosOnShape(int shapeID ) const void SMESH_MesherHelper::setPosOnShapeValidity(int shapeID, bool ok ) const { - std::map< int,bool >::iterator sh_ok = + std::map< int,bool >::iterator sh_ok = ((SMESH_MesherHelper*)this)->myNodePosShapesValidity.insert( make_pair( shapeID, ok)).first; if ( !ok ) sh_ok->second = ok; @@ -591,7 +591,7 @@ void SMESH_MesherHelper::setPosOnShapeValidity(int shapeID, bool ok ) const //======================================================================= //function : ToFixNodeParameters -//purpose : Enables fixing node parameters on EDGEs and FACEs in +//purpose : Enables fixing node parameters on EDGEs and FACEs in // GetNodeU(...,check=true), GetNodeUV(...,check=true), CheckNodeUV() and // CheckNodeU() in case if a node lies on a shape set via SetSubShape(). // Default is False @@ -943,7 +943,7 @@ namespace { gp_XY AverageUV(const gp_XY& uv1, const gp_XY& uv2) { return ( uv1 + uv2 ) / 2.; } gp_XY_FunPtr(Added); // define gp_XY_Added pointer to function calling gp_XY::Added(gp_XY) - gp_XY_FunPtr(Subtracted); + gp_XY_FunPtr(Subtracted); } //======================================================================= @@ -967,9 +967,9 @@ gp_XY SMESH_MesherHelper::ApplyIn2D(Handle(Geom_Surface) surface, return fun(uv1,uv2); // move uv2 not far than half-period from uv1 - double u2 = + double u2 = uv2.X()+(isUPeriodic ? ShapeAnalysis::AdjustByPeriod(uv2.X(),uv1.X(),surface->UPeriod()) :0); - double v2 = + double v2 = uv2.Y()+(isVPeriodic ? ShapeAnalysis::AdjustByPeriod(uv2.Y(),uv1.Y(),surface->VPeriod()) :0); // execute operation @@ -1038,8 +1038,8 @@ gp_XY SMESH_MesherHelper::GetMiddleUV(const Handle(Geom_Surface)& surface, //======================================================================= gp_XY SMESH_MesherHelper::GetCenterUV(const gp_XY& uv1, - const gp_XY& uv2, - const gp_XY& uv3, + const gp_XY& uv2, + const gp_XY& uv3, const gp_XY& uv12, const gp_XY& uv23, const gp_XY& uv31, @@ -1370,7 +1370,7 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetCentralNode(const SMDS_MeshNode* n1, TBiQuad keyOfMap(n1,n2,n3,n4); std::map::iterator itMapCentralNode; itMapCentralNode = myMapWithCentralNode.find( keyOfMap ); - if ( itMapCentralNode != myMapWithCentralNode.end() ) + if ( itMapCentralNode != myMapWithCentralNode.end() ) { return (*itMapCentralNode).second; } @@ -1385,9 +1385,9 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetCentralNode(const SMDS_MeshNode* n1, std::map< int, int > faceId2nbNodes; std::map< int, int > ::iterator itMapWithIdFace; - + SMESHDS_Mesh* meshDS = GetMeshDS(); - + // check if a face lies on a FACE, i.e. its all corner nodes lie either on the FACE or // on sub-shapes of the FACE if ( GetMesh()->HasShapeToMesh() ) @@ -1545,7 +1545,7 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetCentralNode(const SMDS_MeshNode* n1, TBiQuad keyOfMap(n1,n2,n3); std::map::iterator itMapCentralNode; itMapCentralNode = myMapWithCentralNode.find( keyOfMap ); - if ( itMapCentralNode != myMapWithCentralNode.end() ) + if ( itMapCentralNode != myMapWithCentralNode.end() ) { return (*itMapCentralNode).second; } @@ -1560,9 +1560,9 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetCentralNode(const SMDS_MeshNode* n1, std::map< int, int > faceId2nbNodes; std::map< int, int > ::iterator itMapWithIdFace; - + SMESHDS_Mesh* meshDS = GetMeshDS(); - + // check if a face lies on a FACE, i.e. its all corner nodes lie either on the FACE or // on sub-shapes of the FACE if ( GetMesh()->HasShapeToMesh() ) @@ -2004,7 +2004,7 @@ SMDS_MeshEdge* SMESH_MesherHelper::AddEdge(const SMDS_MeshNode* n1, const bool force3d) { SMESHDS_Mesh * meshDS = GetMeshDS(); - + SMDS_MeshEdge* edge = 0; if (myCreateQuadratic) { const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d); @@ -2467,7 +2467,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, const SMDS_MeshNode* n10, const SMDS_MeshNode* n11, const SMDS_MeshNode* n12, - const smIdType id, + const smIdType id, bool /*force3d*/) { SMESHDS_Mesh * meshDS = GetMeshDS(); @@ -3206,7 +3206,7 @@ bool SMESH_MesherHelper::IsSubShape( const TopoDS_Shape& shape, //======================================================================= //function : IsSubShape -//purpose : +//purpose : //======================================================================= bool SMESH_MesherHelper::IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMesh ) @@ -3221,7 +3221,7 @@ bool SMESH_MesherHelper::IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMes //======================================================================= //function : IsBlock -//purpose : +//purpose : //======================================================================= bool SMESH_MesherHelper::IsBlock( const TopoDS_Shape& shape ) @@ -3323,9 +3323,7 @@ double SMESH_MesherHelper::GetAngle( const TopoDS_Edge & theE1, vecRef = du ^ dv; if ( ++nbLoops > 10 ) { - if (SALOME::VerbosityActivated()) - cout << "SMESH_MesherHelper::GetAngle(): Captured in a sigularity" << endl; - + MESSAGE("SMESH_MesherHelper::GetAngle(): Captured in a singularity"); return angle; } } @@ -3404,7 +3402,7 @@ TopoDS_Vertex SMESH_MesherHelper::IthVertex( const bool is2nd, //================================================================================ /*! - * \brief Return type of shape contained in a group + * \brief Return type of shape contained in a group * \param group - a shape of type TopAbs_COMPOUND * \param avoidCompound - not to return TopAbs_COMPOUND */ @@ -3464,13 +3462,13 @@ SMESH_MesherHelper:: MType SMESH_MesherHelper::IsQuadraticMesh() NbAllEdgsAndFaces = myMesh->NbEdges() + myMesh->NbFaces(); if ( NbAllEdgsAndFaces == 0 ) return SMESH_MesherHelper::LINEAR; - + //Quadratic faces and edges NbQuadFacesAndEdgs = myMesh->NbEdges(ORDER_QUADRATIC) + myMesh->NbFaces(ORDER_QUADRATIC); //Linear faces and edges NbFacesAndEdges = myMesh->NbEdges(ORDER_LINEAR) + myMesh->NbFaces(ORDER_LINEAR); - + if (NbAllEdgsAndFaces == NbQuadFacesAndEdgs) { //Quadratic mesh return SMESH_MesherHelper::QUADRATIC; @@ -4115,7 +4113,7 @@ namespace { // Structures used by FixQuadraticElements() } } else if ( _sides.size() < 4 ) - return thePrevLen; + return thePrevLen; // propagate to adjacent faces till limit step or boundary double len1 = thePrevLen + (theLink->MiddlePnt() - _sides[iL1]->MiddlePnt()).Modulus(); @@ -4205,7 +4203,7 @@ namespace { // Structures used by FixQuadraticElements() void QLink::SetContinuesFaces() const { // x0 x - QLink, [-|] - QFace, v - volume - // v0 | v1 + // v0 | v1 // | Between _faces of link x2 two vertical faces are continues // x1----x2-----x3 and two horizontal faces are continues. We set vertical faces // | to _faces[0] and _faces[1] and horizontal faces to @@ -4312,7 +4310,7 @@ namespace { // Structures used by FixQuadraticElements() } return isStraight; } - + //================================================================================ /*! * \brief Move medium nodes of vertical links of pentahedrons adjacent by side faces @@ -4441,13 +4439,13 @@ namespace { // Structures used by FixQuadraticElements() while ( startLink != linksEnd) // loop on columns { // We suppose we have a rectangular structure like shown here. We have found a - // corner of the rectangle (startCorner) and a boundary link sharing - // |/ |/ | the startCorner (startLink). We are going to loop on rows of the - // --o---o---o structure making several chains at once. One chain (columnChain) - // |\ | /| starts at startLink and continues upward (we look at the structure - // \ | \ | / | from such point that startLink is on the bottom of the structure). - // \| \|/ | While going upward we also fill horizontal chains (rowChains) we - // --o---o---o encounter. + // corner of the rectangle (startCorner) and a boundary link sharing + // |/ |/ | the startCorner (startLink). We are going to loop on rows of the + // --o---o---o structure making several chains at once. One chain (columnChain) + // |\ | /| starts at startLink and continues upward (we look at the structure + // \ | \ | / | from such point that startLink is on the bottom of the structure). + // \| \|/ | While going upward we also fill horizontal chains (rowChains) we + // --o---o---o encounter. // /|\ |\ | // / | \ | \ | startCorner // | \| \|,' @@ -4710,7 +4708,7 @@ namespace { // Structures used by FixQuadraticElements() continue; gp_XYZ edgeDir = SMESH_TNodeXYZ( nOnEdge[0] ) - SMESH_TNodeXYZ( nOnEdge[1] ); gp_XYZ edgeNorm = faceNorm ^ edgeDir; - n = theHelper.GetMediumNode( nOnEdge[0], nOnEdge[1], true ); // find n, not create + n = theHelper.GetMediumNode( nOnEdge[0], nOnEdge[1], true ); // find n, not create gp_XYZ pN0 = SMESH_TNodeXYZ( nOnEdge[0] ); gp_XYZ pMedium = SMESH_TNodeXYZ( n ); // on-edge node location gp_XYZ pFaceN = SMESH_TNodeXYZ( nOnFace ); // on-face node location @@ -4991,7 +4989,7 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, // fix nodes on geom faces int nbfaces = faces.Extent(); - + for ( TopTools_MapIteratorOfMapOfShape fIt( faces ); fIt.More(); fIt.Next() ) { MESSAGE("FIX FACE " << nbfaces-- << " #" << GetMeshDS()->ShapeToIndex(fIt.Key())); MSG("FIX FACE " << nbfaces-- << " #" << GetMeshDS()->ShapeToIndex(fIt.Key())); @@ -5436,7 +5434,7 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, { uv[ i ] = GetNodeUV( F, nodes[i], nodes[8], &checkUV ); // as this method is used after mesh generation, UV of nodes is not - // updated according to bending links, so we update + // updated according to bending links, so we update if ( i > 3 && nodes[i]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) CheckNodeUV( F, nodes[i], uv[ i ], 2*tol, /*force=*/true ); } @@ -5471,7 +5469,7 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, { uv[ i ] = GetNodeUV( F, nodes[i], nodes[(i+1)%3], &uvOK ); // as this method is used after mesh generation, UV of nodes is not - // updated according to bending links, so we update + // updated according to bending links, so we update if ( nodes[i]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) CheckNodeUV( F, nodes[i], uv[ i ], 2*tol, /*force=*/true ); } @@ -5538,16 +5536,16 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, pointsOnShapes[ SMESH_Block::ID_Ex11 ] = SMESH_TNodeXYZ( hexNodes[ 13 ] ); pointsOnShapes[ SMESH_Block::ID_E0y1 ] = SMESH_TNodeXYZ( hexNodes[ 12 ] ); pointsOnShapes[ SMESH_Block::ID_E1y1 ] = SMESH_TNodeXYZ( hexNodes[ 14 ] ); - pointsOnShapes[ SMESH_Block::ID_E00z ] = SMESH_TNodeXYZ( hexNodes[ 16 ] ); - pointsOnShapes[ SMESH_Block::ID_E10z ] = SMESH_TNodeXYZ( hexNodes[ 19 ] ); - pointsOnShapes[ SMESH_Block::ID_E01z ] = SMESH_TNodeXYZ( hexNodes[ 17 ] ); + pointsOnShapes[ SMESH_Block::ID_E00z ] = SMESH_TNodeXYZ( hexNodes[ 16 ] ); + pointsOnShapes[ SMESH_Block::ID_E10z ] = SMESH_TNodeXYZ( hexNodes[ 19 ] ); + pointsOnShapes[ SMESH_Block::ID_E01z ] = SMESH_TNodeXYZ( hexNodes[ 17 ] ); pointsOnShapes[ SMESH_Block::ID_E11z ] = SMESH_TNodeXYZ( hexNodes[ 18 ] ); pointsOnShapes[ SMESH_Block::ID_Fxy0 ] = SMESH_TNodeXYZ( hexNodes[ 20 ] ); pointsOnShapes[ SMESH_Block::ID_Fxy1 ] = SMESH_TNodeXYZ( hexNodes[ 25 ] ); - pointsOnShapes[ SMESH_Block::ID_Fx0z ] = SMESH_TNodeXYZ( hexNodes[ 21 ] ); - pointsOnShapes[ SMESH_Block::ID_Fx1z ] = SMESH_TNodeXYZ( hexNodes[ 23 ] ); - pointsOnShapes[ SMESH_Block::ID_F0yz ] = SMESH_TNodeXYZ( hexNodes[ 24 ] ); + pointsOnShapes[ SMESH_Block::ID_Fx0z ] = SMESH_TNodeXYZ( hexNodes[ 21 ] ); + pointsOnShapes[ SMESH_Block::ID_Fx1z ] = SMESH_TNodeXYZ( hexNodes[ 23 ] ); + pointsOnShapes[ SMESH_Block::ID_F0yz ] = SMESH_TNodeXYZ( hexNodes[ 24 ] ); pointsOnShapes[ SMESH_Block::ID_F1yz ] = SMESH_TNodeXYZ( hexNodes[ 22 ] ); gp_XYZ nCenterParams(0.5, 0.5, 0.5), nCenterCoords; @@ -5584,7 +5582,6 @@ void SMESH_MesherHelper::WriteShape(const TopoDS_Shape& s) { const char* name = "/tmp/shape.brep"; BRepTools::Write( s, name ); - if (SALOME::VerbosityActivated()) - std::cout << name << std::endl; + MESSAGE(name); } diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 0b697d7a0..76dfb83e1 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -37,6 +37,7 @@ #include "SMESH_Mesh.hxx" #include "SMESH_MesherHelper.hxx" #include "SMESH_subMeshEventListener.hxx" +#include "SMESH_MeshLocker.hxx" #include "utilities.h" #include "Basics_Utils.hxx" @@ -62,7 +63,7 @@ using namespace std; #ifdef _DEBUG_ // enable printing algo + shape id + hypo used while meshing -//#define PRINT_WHO_COMPUTE_WHAT +#define PRINT_WHO_COMPUTE_WHAT #endif //============================================================================= @@ -256,7 +257,7 @@ bool SMESH_subMesh::IsMeshComputed() const TopExp_Explorer exp( _subShape, (TopAbs_ShapeEnum) type ); for ( ; exp.More(); exp.Next() ) { - if ( SMESHDS_SubMesh * smDS = meshDS->MeshElements( exp.Current() )) + if ( SMESHDS_SubMesh * smDS = meshDS->MeshElements( exp.Current() ) ) { bool computed = (dim > 0) ? smDS->NbElements() : smDS->NbNodes(); if ( computed ) @@ -609,7 +610,7 @@ bool SMESH_subMesh::IsApplicableHypothesis(const SMESH_Hypothesis* theHypothesis * \param [in] event - what happens * \param [in] anHyp - a hypothesis * \return SMESH_Hypothesis::Hypothesis_Status - a treatment result. - * + * * Optional description of a problematic situation (if any) can be retrieved * via GetComputeError(). */ @@ -1033,8 +1034,8 @@ SMESH_Hypothesis::Hypothesis_Status // detect algorithm hiding // - if ( ret == SMESH_Hypothesis::HYP_OK && - ( event == ADD_ALGO || event == ADD_FATHER_ALGO ) && algo && + if ( ret == SMESH_Hypothesis::HYP_OK && + ( event == ADD_ALGO || event == ADD_FATHER_ALGO ) && algo && algo->GetName() == anHyp->GetName() ) { // is algo hidden? @@ -1392,6 +1393,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) else if (( event == COMPUTE || event == COMPUTE_SUBMESH ) && !_alwaysComputed ) { + SMESH_MeshLocker myLocker(_father); const TopoDS_Vertex & V = TopoDS::Vertex( _subShape ); gp_Pnt P = BRep_Tool::Pnt(V); if ( SMDS_MeshNode * n = _father->GetMeshDS()->AddNode(P.X(), P.Y(), P.Z()) ) { @@ -1511,9 +1513,10 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) break; } TopoDS_Shape shape = _subShape; - algo->SubMeshesToCompute().assign( 1, this ); + algo->setSubMeshesToCompute(this); // check submeshes needed - if (_father->HasShapeToMesh() ) { + // In parallel there would be no submesh to check + if (_father->HasShapeToMesh() && !_father->IsParallel()) { bool subComputed = false, subFailed = false; if (!algo->OnlyUnaryInput()) { // --- commented for bos#22320 to compute all sub-shapes at once if possible; @@ -1575,7 +1578,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) _computeError = SMESH_ComputeError::Worst( _computeError, algo->GetComputeError() ); } catch ( ::SMESH_ComputeError& comperr ) { - cout << " SMESH_ComputeError caught" << endl; + MESSAGE(" SMESH_ComputeError caught"); if ( !_computeError ) _computeError = SMESH_ComputeError::New(); *_computeError = comperr; } @@ -1642,8 +1645,9 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) #ifdef PRINT_WHO_COMPUTE_WHAT for (subS.ReInit(); subS.More(); subS.Next()) { + SMESH_MeshLocker myLocker(_father); const std::list & hyps = - _algo->GetUsedHypothesis( *_father, _subShape ); + _algo->GetUsedHypothesis( *_father, _subShape ); SMESH_Comment hypStr; if ( !hyps.empty() ) { @@ -2097,7 +2101,7 @@ void SMESH_subMesh::updateDependantsState(const compute_event theEvent) //======================================================================= //function : cleanDependants -//purpose : +//purpose : //======================================================================= void SMESH_subMesh::cleanDependants() @@ -2121,7 +2125,7 @@ void SMESH_subMesh::cleanDependants() //======================================================================= //function : removeSubMeshElementsAndNodes -//purpose : +//purpose : //======================================================================= void SMESH_subMesh::removeSubMeshElementsAndNodes() @@ -2297,7 +2301,7 @@ SMESH_subMesh::OwnListenerData::OwnListenerData( SMESH_subMesh* sm, EventListene * \param listener - the listener to store * \param data - the listener data to store * \param where - the submesh to store the listener and it's data - * + * * It remembers the submesh where it puts the listener in order to delete * them when HYP_OK algo_state is lost * After being set, event listener is notified on each event of where submesh. @@ -2319,7 +2323,7 @@ void SMESH_subMesh::SetEventListener(EventListener* listener, * \brief Sets an event listener and its data to a submesh * \param listener - the listener to store * \param data - the listener data to store - * + * * After being set, event listener is notified on each event of a submesh. */ //================================================================================ @@ -2529,7 +2533,7 @@ void SMESH_subMesh::loadDependentMeshes() * \param subMesh - the submesh where the event occurs * \param data - listener data stored in the subMesh * \param hyp - hypothesis, if eventType is algo_event - * + * * The base implementation translates CLEAN event to the subMesh * stored in listener data. Also it sends SUBMESH_COMPUTED event in case of * successful COMPUTE event. diff --git a/src/SMESH/SMESH_subMesh.hxx b/src/SMESH/SMESH_subMesh.hxx index fbfd222c2..0f925570a 100644 --- a/src/SMESH/SMESH_subMesh.hxx +++ b/src/SMESH/SMESH_subMesh.hxx @@ -69,7 +69,7 @@ class SMESH_EXPORT SMESH_subMesh int GetId() const; // == meshDS->ShapeToIndex( aSubShape ) SMESH_Mesh* GetFather() { return _father; } - + SMESHDS_SubMesh * GetSubMeshDS(); const SMESHDS_SubMesh * GetSubMeshDS() const; @@ -79,6 +79,7 @@ class SMESH_EXPORT SMESH_subMesh SMESH_subMesh *GetFirstToCompute(); SMESH_Algo* GetAlgo() const; + SMESH_Algo* CopyAlgo() const; const std::map < int, SMESH_subMesh * >& DependsOn(); bool DependsOn( const SMESH_subMesh* other ) const; @@ -123,7 +124,7 @@ class SMESH_EXPORT SMESH_subMesh }; // ================================================================== - // Members to track non hierarchical dependencies between sub-meshes + // Members to track non hierarchical dependencies between sub-meshes // ================================================================== /*! @@ -131,7 +132,7 @@ class SMESH_EXPORT SMESH_subMesh * \param listener - the listener to store * \param data - the listener data to store * \param where - the submesh to store the listener and it's data - * + * * The method remembers the submesh \awhere it puts the listener in order to delete * it when HYP_OK algo_state is lost * After being set, event listener is notified on each event of \awhere submesh. @@ -185,7 +186,7 @@ protected: * \brief Sets an event listener and its data to a submesh * \param listener - the listener to store * \param data - the listener data to store - * + * * After being set, event listener is notified on each event of a submesh. */ void setEventListener(EventListener* listener, EventListenerData* data); @@ -245,7 +246,7 @@ public: bool IsApplicableHypothesis(const SMESH_Hypothesis* theHypothesis) const; // return true if theHypothesis can be used to mesh me: // its shape type is checked - + SMESH_Hypothesis::Hypothesis_Status CheckConcurrentHypothesis (SMESH_Hypothesis* theHypothesis); // check if there are several applicable hypothesis on fathers @@ -277,7 +278,7 @@ public: int GetComputeCost() const; // how costly is to compute this sub-mesh - + /*! * \brief Find common submeshes (based on shared subshapes with other * \param theOther submesh to check @@ -319,7 +320,7 @@ protected: /*! * \brief Return a hypothesis attached to theShape. - * + * * If theHyp is provided, similar but not same hypotheses * is returned; else an applicable ones having theHypType * is returned @@ -327,7 +328,7 @@ protected: const SMESH_Hypothesis* getSimilarAttached(const TopoDS_Shape& theShape, const SMESH_Hypothesis * theHyp, const int theHypType = 0); - // + // int computeCost() const; protected: diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx index 563e2de98..7d241698f 100644 --- a/src/SMESHDS/SMESHDS_Mesh.cxx +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -99,7 +99,7 @@ int SMESHDS_Mesh::GetPersistentId() const //======================================================================= //function : ShapeToMesh -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S) { @@ -141,7 +141,7 @@ void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S) //======================================================================= //function : AddHypothesis -//purpose : +//purpose : //======================================================================= bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS, @@ -165,7 +165,7 @@ bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS, //======================================================================= //function : RemoveHypothesis -//purpose : +//purpose : //======================================================================= bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S, @@ -186,7 +186,7 @@ bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S, //======================================================================= //function : AddNode -//purpose : +//purpose : //======================================================================= SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z) { @@ -204,7 +204,7 @@ SMDS_MeshNode* SMESHDS_Mesh::AddNodeWithID(double x, double y, double z, smIdTyp //======================================================================= //function : MoveNode -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z) @@ -235,7 +235,7 @@ bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, //======================================================================= //function : ChangePolygonNodes -//purpose : +//purpose : //======================================================================= bool SMESHDS_Mesh::ChangePolygonNodes (const SMDS_MeshElement * elem, std::vector& nodes) @@ -309,7 +309,7 @@ SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElement(const SMDS_MeshNode * node) //======================================================================= //function :AddBallWithID -//purpose : +//purpose : //======================================================================= SMDS_BallElement* SMESHDS_Mesh::AddBallWithID(smIdType node, double diameter, smIdType ID) @@ -338,7 +338,7 @@ SMDS_BallElement* SMESHDS_Mesh::AddBall (const SMDS_MeshNode * node, //======================================================================= //function :AddEdgeWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(smIdType n1, smIdType n2, smIdType ID) @@ -349,7 +349,7 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(smIdType n1, smIdType n2, smIdType ID } SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, + const SMDS_MeshNode * n2, smIdType ID) { return AddEdgeWithID(n1->GetID(), @@ -361,15 +361,15 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2) { SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2); - if(anElem) myScript->AddEdge(anElem->GetID(), - n1->GetID(), + if(anElem) myScript->AddEdge(anElem->GetID(), + n1->GetID(), n2->GetID()); return anElem; } //======================================================================= //function :AddFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType ID) { @@ -380,7 +380,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, + const SMDS_MeshNode * n3, smIdType ID) { return AddFaceWithID(n1->GetID(), @@ -394,8 +394,8 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1, const SMDS_MeshNode * n3) { SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3); - if(anElem) myScript->AddFace(anElem->GetID(), - n1->GetID(), + if(anElem) myScript->AddFace(anElem->GetID(), + n1->GetID(), n2->GetID(), n3->GetID()); return anElem; @@ -403,7 +403,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1, //======================================================================= //function :AddFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType ID) { @@ -415,7 +415,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, + const SMDS_MeshNode * n4, smIdType ID) { return AddFaceWithID(n1->GetID(), @@ -431,9 +431,9 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4) { SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4); - if(anElem) myScript->AddFace(anElem->GetID(), - n1->GetID(), - n2->GetID(), + if(anElem) myScript->AddFace(anElem->GetID(), + n1->GetID(), + n2->GetID(), n3->GetID(), n4->GetID()); return anElem; @@ -441,7 +441,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, //======================================================================= //function :AddVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType ID) { @@ -453,11 +453,11 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdTyp SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, + const SMDS_MeshNode * n4, smIdType ID) { - return AddVolumeWithID(n1->GetID(), - n2->GetID(), + return AddVolumeWithID(n1->GetID(), + n2->GetID(), n3->GetID(), n4->GetID(), ID); @@ -469,9 +469,9 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4); - if(anElem) myScript->AddVolume(anElem->GetID(), - n1->GetID(), - n2->GetID(), + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), + n2->GetID(), n3->GetID(), n4->GetID()); return anElem; @@ -479,7 +479,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, //======================================================================= //function :AddVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n5, smIdType ID) { @@ -492,13 +492,13 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, + const SMDS_MeshNode * n5, smIdType ID) { - return AddVolumeWithID(n1->GetID(), - n2->GetID(), + return AddVolumeWithID(n1->GetID(), + n2->GetID(), n3->GetID(), - n4->GetID(), + n4->GetID(), n5->GetID(), ID); } @@ -510,18 +510,18 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n5) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5); - if(anElem) myScript->AddVolume(anElem->GetID(), - n1->GetID(), - n2->GetID(), + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), + n2->GetID(), n3->GetID(), - n4->GetID(), + n4->GetID(), n5->GetID()); return anElem; } //======================================================================= //function :AddVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n5, smIdType n6, smIdType ID) { @@ -535,14 +535,14 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n6, smIdType ID) { - return AddVolumeWithID(n1->GetID(), - n2->GetID(), + return AddVolumeWithID(n1->GetID(), + n2->GetID(), n3->GetID(), - n4->GetID(), - n5->GetID(), + n4->GetID(), + n5->GetID(), n6->GetID(), ID); } @@ -555,19 +555,19 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n6) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6); - if(anElem) myScript->AddVolume(anElem->GetID(), - n1->GetID(), - n2->GetID(), + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), + n2->GetID(), n3->GetID(), - n4->GetID(), - n5->GetID(), + n4->GetID(), + n5->GetID(), n6->GetID()); return anElem; } //======================================================================= //function :AddVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n5, smIdType n6, smIdType n7, smIdType n8, smIdType ID) { @@ -583,16 +583,16 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n5, const SMDS_MeshNode * n6, const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, + const SMDS_MeshNode * n8, smIdType ID) { - return AddVolumeWithID(n1->GetID(), - n2->GetID(), + return AddVolumeWithID(n1->GetID(), + n2->GetID(), n3->GetID(), - n4->GetID(), - n5->GetID(), - n6->GetID(), - n7->GetID(), + n4->GetID(), + n5->GetID(), + n6->GetID(), + n7->GetID(), n8->GetID(), ID); } @@ -607,14 +607,14 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n8) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8); - if(anElem) myScript->AddVolume(anElem->GetID(), - n1->GetID(), - n2->GetID(), + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), + n2->GetID(), n3->GetID(), - n4->GetID(), - n5->GetID(), - n6->GetID(), - n7->GetID(), + n4->GetID(), + n5->GetID(), + n6->GetID(), + n7->GetID(), n8->GetID()); return anElem; } @@ -641,14 +641,14 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n5, const SMDS_MeshNode * n6, const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, - const SMDS_MeshNode * n9, - const SMDS_MeshNode * n10, - const SMDS_MeshNode * n11, - const SMDS_MeshNode * n12, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n9, + const SMDS_MeshNode * n10, + const SMDS_MeshNode * n11, + const SMDS_MeshNode * n12, smIdType ID) { - return AddVolumeWithID(n1->GetID(), + return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), @@ -670,14 +670,14 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n5, const SMDS_MeshNode * n6, const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, - const SMDS_MeshNode * n9, - const SMDS_MeshNode * n10, - const SMDS_MeshNode * n11, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n9, + const SMDS_MeshNode * n10, + const SMDS_MeshNode * n11, const SMDS_MeshNode * n12) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12); - if(anElem) myScript->AddVolume(anElem->GetID(), + if(anElem) myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(), n3->GetID(), @@ -696,7 +696,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, //======================================================================= //function : AddPolygonalFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (const std::vector& nodes_ids, const smIdType ID) @@ -742,7 +742,7 @@ SMESHDS_Mesh::AddPolygonalFace (const std::vector& nodes) //======================================================================= //function : AddQuadPolygonalFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector& nodes_ids, const smIdType ID) @@ -788,7 +788,7 @@ SMESHDS_Mesh::AddQuadPolygonalFace (const std::vector& nod //======================================================================= //function : AddPolyhedralVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (const std::vector& nodes_ids, const std::vector& quantities, @@ -836,7 +836,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume //======================================================================= //function : removeFromContainers -//purpose : +//purpose : //======================================================================= static void removeFromContainers (SMESHDS_Mesh* /*theMesh*/, @@ -905,8 +905,8 @@ void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n) } if ( SMESHDS_SubMesh * sm = MeshElements( n->getshapeId() )) sm->RemoveNode( n ); - - + + std::vector removedElems; std::vector removedNodes; @@ -918,7 +918,7 @@ void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n) //======================================================================= //function : RemoveFreeNode -//purpose : +//purpose : //======================================================================= bool SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n, SMESHDS_SubMesh * subMesh, @@ -971,20 +971,20 @@ void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt) RemoveFreeElement( elt, subMesh, true ); return; } - + myScript->RemoveElement(elt->GetID()); std::vector removedElems; std::vector removedNodes; SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes ); - + removeFromContainers( this, myGroups, removedElems ); } //======================================================================= //function : RemoveFreeElement -//purpose : +//purpose : //======================================================================== void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt, SMESHDS_SubMesh * subMesh, @@ -1151,7 +1151,7 @@ void SMESHDS_Mesh::SetNodeOnVertex(const SMDS_MeshNode * aNode, //======================================================================= //function : UnSetNodeOnShape -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode) { @@ -1173,7 +1173,7 @@ void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement, //======================================================================= //function : UnSetMeshElementOnShape -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem, const TopoDS_Shape & S) @@ -1184,7 +1184,7 @@ void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem, //======================================================================= //function : ShapeToMesh -//purpose : +//purpose : //======================================================================= TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const { @@ -1229,7 +1229,7 @@ SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index) const //======================================================================= //function : SubMeshIndices -//purpose : +//purpose : //======================================================================= std::list SMESHDS_Mesh::SubMeshIndices() const { @@ -1243,7 +1243,7 @@ std::list SMESHDS_Mesh::SubMeshIndices() const //======================================================================= //function : SubMeshes -//purpose : +//purpose : //======================================================================= SMESHDS_SubMeshIteratorPtr SMESHDS_Mesh::SubMeshes() const @@ -1253,7 +1253,7 @@ SMESHDS_SubMeshIteratorPtr SMESHDS_Mesh::SubMeshes() const //======================================================================= //function : GetHypothesis -//purpose : +//purpose : //======================================================================= const std::list& @@ -1283,7 +1283,7 @@ bool SMESHDS_Mesh::IsUsedHypothesis(const SMESHDS_Hypothesis * H) const //======================================================================= //function : GetScript -//purpose : +//purpose : //======================================================================= SMESHDS_Script* SMESHDS_Mesh::GetScript() { @@ -1292,7 +1292,7 @@ SMESHDS_Script* SMESHDS_Mesh::GetScript() //======================================================================= //function : ClearScript -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::ClearScript() { @@ -1301,7 +1301,7 @@ void SMESHDS_Mesh::ClearScript() //======================================================================= //function : HasMeshElements -//purpose : +//purpose : //======================================================================= bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S) const { @@ -1311,7 +1311,7 @@ bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S) const //======================================================================= //function : HasHypothesis -//purpose : +//purpose : //======================================================================= bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S) { @@ -1319,8 +1319,8 @@ bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S) } //======================================================================= -//function : NewSubMesh -//purpose : +//function : NewSubMesh +//purpose : //======================================================================= SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index) { @@ -1335,7 +1335,7 @@ SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index) //======================================================================= //function : AddCompoundSubmesh -//purpose : +//purpose : //======================================================================= int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S, @@ -1370,7 +1370,7 @@ int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S, //======================================================================= //function : IndexToShape -//purpose : +//purpose : //======================================================================= const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const { @@ -1399,7 +1399,7 @@ int SMESHDS_Mesh::MaxSubMeshIndex() const //======================================================================= //function : ShapeToIndex -//purpose : +//purpose : //======================================================================= int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const { @@ -1409,7 +1409,7 @@ int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const //======================================================================= //function : SetNodeOnVolume -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index) { @@ -1457,7 +1457,7 @@ void SMESHDS_Mesh::SetNodeOnVertex(const SMDS_MeshNode* aNode, int Index) //======================================================================= //function : SetMeshElementOnShape -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement, int Index) @@ -1467,7 +1467,7 @@ void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement, //======================================================================= //function : ~SMESHDS_Mesh -//purpose : +//purpose : //======================================================================= SMESHDS_Mesh::~SMESHDS_Mesh() { @@ -1488,9 +1488,9 @@ SMESHDS_Mesh::~SMESHDS_Mesh() //======================================================================= //function : AddEdgeWithID -//purpose : +//purpose : //======================================================================= -SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(smIdType n1, smIdType n2, smIdType n12, smIdType ID) +SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(smIdType n1, smIdType n2, smIdType n12, smIdType ID) { SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID); if(anElem) myScript->AddEdge(ID,n1,n2,n12); @@ -1499,15 +1499,15 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(smIdType n1, smIdType n2, smIdType n1 //======================================================================= //function : AddEdge -//purpose : +//purpose : //======================================================================= SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, const SMDS_MeshNode* n12) { SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12); - if(anElem) myScript->AddEdge(anElem->GetID(), - n1->GetID(), + if(anElem) myScript->AddEdge(anElem->GetID(), + n1->GetID(), n2->GetID(), n12->GetID()); return anElem; @@ -1515,11 +1515,11 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1, //======================================================================= //function : AddEdgeWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n12, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12, smIdType ID) { return AddEdgeWithID(n1->GetID(), @@ -1531,7 +1531,7 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, //======================================================================= //function : AddFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -1541,7 +1541,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n31) { SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31); - if(anElem) myScript->AddFace(anElem->GetID(), + if(anElem) myScript->AddFace(anElem->GetID(), n1->GetID(), n2->GetID(), n3->GetID(), n12->GetID(), n23->GetID(), n31->GetID()); return anElem; @@ -1549,7 +1549,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n12,smIdType n23,smIdType n31, smIdType ID) @@ -1561,14 +1561,14 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3 //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, + const SMDS_MeshNode * n31, smIdType ID) { return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), @@ -1578,7 +1578,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, //======================================================================= //function : AddFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -1589,7 +1589,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * nCenter) { SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31,nCenter); - if(anElem) myScript->AddFace(anElem->GetID(), + if(anElem) myScript->AddFace(anElem->GetID(), n1->GetID(), n2->GetID(), n3->GetID(), n12->GetID(), n23->GetID(), n31->GetID(), nCenter->GetID()); @@ -1598,7 +1598,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n12,smIdType n23,smIdType n31, smIdType nCenter, smIdType ID) @@ -1610,15 +1610,15 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3 //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, - const SMDS_MeshNode * nCenter, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * nCenter, smIdType ID) { return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), @@ -1629,7 +1629,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, //======================================================================= //function : AddFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -1641,7 +1641,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n41) { SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41); - if(anElem) myScript->AddFace(anElem->GetID(), + if(anElem) myScript->AddFace(anElem->GetID(), n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID()); return anElem; @@ -1649,7 +1649,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n12,smIdType n23,smIdType n34,smIdType n41, smIdType ID) @@ -1661,7 +1661,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3 //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -1669,8 +1669,8 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, smIdType ID) { return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), @@ -1681,7 +1681,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, //======================================================================= //function : AddFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -1690,11 +1690,11 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, + const SMDS_MeshNode * n41, const SMDS_MeshNode * nCenter) { SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41,nCenter); - if(anElem) myScript->AddFace(anElem->GetID(), + if(anElem) myScript->AddFace(anElem->GetID(), n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), nCenter->GetID()); @@ -1703,7 +1703,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n12,smIdType n23,smIdType n34,smIdType n41, @@ -1716,7 +1716,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3 //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -1724,9 +1724,9 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, - const SMDS_MeshNode * nCenter, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * nCenter, smIdType ID) { return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), @@ -1737,21 +1737,21 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, //======================================================================= //function : AddVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, + const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n31, - const SMDS_MeshNode * n14, + const SMDS_MeshNode * n14, const SMDS_MeshNode * n24, const SMDS_MeshNode * n34) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34); - if(anElem) myScript->AddVolume(anElem->GetID(), + if(anElem) myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), n12->GetID(), n23->GetID(), n31->GetID(), n14->GetID(), n24->GetID(), n34->GetID()); @@ -1760,7 +1760,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, //======================================================================= //function : AddVolumeWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n12,smIdType n23,smIdType n31, @@ -1771,7 +1771,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdTyp if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34); return anElem; } - + //======================================================================= //function : AddVolumeWithID //purpose : 2d order tetrahedron of 10 nodes @@ -1783,7 +1783,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n31, - const SMDS_MeshNode * n14, + const SMDS_MeshNode * n14, const SMDS_MeshNode * n24, const SMDS_MeshNode * n34, smIdType ID) @@ -1796,18 +1796,18 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, //======================================================================= //function : AddVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, + const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, + const SMDS_MeshNode * n5, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, const SMDS_MeshNode * n41, - const SMDS_MeshNode * n15, + const SMDS_MeshNode * n15, const SMDS_MeshNode * n25, const SMDS_MeshNode * n35, const SMDS_MeshNode * n45) @@ -1824,7 +1824,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, //======================================================================= //function : AddVolumeWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n5, smIdType n12,smIdType n23,smIdType n34,smIdType n41, @@ -1837,7 +1837,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdTyp n15,n25,n35,n45); return anElem; } - + //======================================================================= //function : AddVolumeWithID //purpose : 2d order pyramid of 13 nodes @@ -1846,12 +1846,12 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, + const SMDS_MeshNode * n5, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, const SMDS_MeshNode * n41, - const SMDS_MeshNode * n15, + const SMDS_MeshNode * n15, const SMDS_MeshNode * n25, const SMDS_MeshNode * n35, const SMDS_MeshNode * n45, @@ -1870,17 +1870,17 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, //purpose : 2nd order pentahedron (prism) with 15 nodes //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, + const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, + const SMDS_MeshNode * n31, const SMDS_MeshNode * n45, const SMDS_MeshNode * n56, - const SMDS_MeshNode * n64, + const SMDS_MeshNode * n64, const SMDS_MeshNode * n14, const SMDS_MeshNode * n25, const SMDS_MeshNode * n36) @@ -2000,7 +2000,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdTyp n45,n56,n64,n14,n25,n36, n1245, n2356, n1346); return anElem; } - + //======================================================================= //function : AddVolumeWithID //purpose : 2d order Pentahedron with 18 nodes @@ -2009,14 +2009,14 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, + const SMDS_MeshNode * n31, const SMDS_MeshNode * n45, const SMDS_MeshNode * n56, - const SMDS_MeshNode * n64, + const SMDS_MeshNode * n64, const SMDS_MeshNode * n14, const SMDS_MeshNode * n25, const SMDS_MeshNode * n36, @@ -2039,21 +2039,21 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, //purpose : add quadratic hexahedron //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, + const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, + const SMDS_MeshNode * n8, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, + const SMDS_MeshNode * n41, const SMDS_MeshNode * n56, const SMDS_MeshNode * n67, const SMDS_MeshNode * n78, - const SMDS_MeshNode * n85, + const SMDS_MeshNode * n85, const SMDS_MeshNode * n15, const SMDS_MeshNode * n26, const SMDS_MeshNode * n37, @@ -2075,7 +2075,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, //======================================================================= //function : AddVolumeWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n5, smIdType n6, smIdType n7, smIdType n8, @@ -2091,7 +2091,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdTyp n56,n67,n78,n85,n15,n26,n37,n48); return anElem; } - + //======================================================================= //function : AddVolumeWithID //purpose : 2d order Hexahedrons with 20 nodes @@ -2100,18 +2100,18 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, + const SMDS_MeshNode * n8, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, + const SMDS_MeshNode * n41, const SMDS_MeshNode * n56, const SMDS_MeshNode * n67, const SMDS_MeshNode * n78, - const SMDS_MeshNode * n85, + const SMDS_MeshNode * n85, const SMDS_MeshNode * n15, const SMDS_MeshNode * n26, const SMDS_MeshNode * n37, @@ -2132,25 +2132,25 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, + const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, + const SMDS_MeshNode * n8, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, + const SMDS_MeshNode * n41, const SMDS_MeshNode * n56, const SMDS_MeshNode * n67, const SMDS_MeshNode * n78, - const SMDS_MeshNode * n85, + const SMDS_MeshNode * n85, const SMDS_MeshNode * n15, const SMDS_MeshNode * n26, const SMDS_MeshNode * n37, - const SMDS_MeshNode * n48, + const SMDS_MeshNode * n48, const SMDS_MeshNode * n1234, const SMDS_MeshNode * n1256, const SMDS_MeshNode * n2367, diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index 9b622a1a9..def823814 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -2216,7 +2216,8 @@ bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand ) "GetElemNode","IsMediumNode","IsMediumNodeOfAnyElem","ElemNbEdges","ElemNbFaces", "GetElemFaceNodes", "GetFaceNormal", "FindElementByNodes", "IsPoly","IsQuadratic","BaryCenter","GetHypothesisList", "SetAutoColor", "GetAutoColor", - "Clear", "ConvertToStandalone", "GetMeshOrder", "SetMeshOrder" + "Clear", "ConvertToStandalone", "GetMeshOrder", "SetMeshOrder", + "SetNbThreads" ,"" }; // <- mark of end sameMethods.Insert( names ); } diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index 944251e83..5c72ecf45 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -6643,8 +6643,6 @@ CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char* theAlgoType, SMESH_CATCH( SMESH::doNothing ); - if (SALOME::VerbosityActivated()) - cout << "SMESH_Gen_i::IsApplicable(): exception in " << ( theAlgoType ? theAlgoType : "") << endl; - + MESSAGE("SMESH_Gen_i::IsApplicable(): exception in " << ( theAlgoType ? theAlgoType : "")); return true; } diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index badd43640..7d4bcb418 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -2500,7 +2500,7 @@ void SMESH_Mesh_i::CheckGeomModif( bool theIsBreakLink ) } old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape ); } - + } } // store assigned hypotheses @@ -6161,8 +6161,8 @@ SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh() /*! * \brief Return false if GetMeshInfo() return incorrect information that may * happen if mesh data is not yet fully loaded from the file of study. - * - * + * + * */ //================================================================================ @@ -7028,6 +7028,16 @@ TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes() return res; } +//============================================================================= +/*! + * \brief Set the number of threads for a parallel computation + */ +//============================================================================= +void SMESH_Mesh_i::SetNbThreads(CORBA::Long nbThreads){ + _impl->SetNbThreads(nbThreads); +} + + //============================================================================= /*! * \brief Convert submesh ids into submesh interfaces @@ -7220,7 +7230,7 @@ smIdType SMESH_MeshPartDS::MinNodeID() const { if ( _meshDS ) return _meshDS->MinNodeID(); return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID(); -} +} // ------------------------------------------------------------------------------------- smIdType SMESH_MeshPartDS::MaxElementID() const { diff --git a/src/SMESH_I/SMESH_Mesh_i.hxx b/src/SMESH_I/SMESH_Mesh_i.hxx index 8a50d1226..45928272d 100644 --- a/src/SMESH_I/SMESH_Mesh_i.hxx +++ b/src/SMESH_I/SMESH_Mesh_i.hxx @@ -226,7 +226,7 @@ public: const char* file, CORBA::Boolean withRequiredGroups); - + template void ExportPartToMEDCommon(SPECLS& speCls, SMESH::SMESH_IDSource_ptr meshPart, @@ -571,7 +571,7 @@ public: * Persistence of geometry tick */ int& MainShapeTick() { return _mainShapeTick; } - + /*! * Sets list of notebook variables used for Mesh operations separated by ":" symbol @@ -673,6 +673,8 @@ private: SMESH::submesh_array_array& theSubMeshOrder, const bool theIsDump); + void SetNbThreads(CORBA::Long nbThreads); + /*! * \brief Finds concurrent sub-meshes */ diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index 62db88951..ec65b9fa9 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -462,6 +462,21 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): obj,name = name,obj return Mesh(self, self.geompyD, obj, name) + def ParallelMesh(self, obj, param, nbThreads, name=0): + """ + Create a parallel mesh. + + Parameters: + obj: geometrical object for meshing + name: the name for the new mesh. + param: full mesh parameters + nbThreads: Number of threads for parallelisation. + + Returns: + an instance of class :class:`ParallelMesh`. + """ + return ParallelMesh(self, self.geompyD, obj, param, nbThreads, name) + def RemoveMesh( self, mesh ): """ Delete a mesh @@ -1863,7 +1878,6 @@ class Mesh(metaclass = MeshMeta): geom = self.geom return self.smeshpyD.Evaluate(self.mesh, geom) - def Compute(self, geom=0, discardModifs=False, refresh=False): """ Compute the mesh and return the status of the computation @@ -7487,6 +7501,121 @@ class Mesh(metaclass = MeshMeta): pass # end of Mesh class +def _copy_netgen_param(dim, local_param, global_param): + if dim==1: + #TODO: Try to identify why we need to substract 1 + local_param.NumberOfSegments(int(global_param.GetNbSegPerEdge())-1) + elif dim==2: + local_param.SetMaxSize(global_param.GetMaxSize()) + local_param.SetMinSize(global_param.GetMinSize()) + local_param.SetOptimize(global_param.GetOptimize()) + local_param.SetFineness(global_param.GetFineness()) + local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge()) + local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius()) + local_param.SetGrowthRate(global_param.GetGrowthRate()*0.9) + local_param.SetChordalError(global_param.GetChordalError()) + local_param.SetChordalErrorEnabled(global_param.GetChordalErrorEnabled()) + local_param.SetUseSurfaceCurvature(global_param.GetUseSurfaceCurvature()) + local_param.SetUseDelauney(global_param.GetUseDelauney()) + local_param.SetQuadAllowed(global_param.GetQuadAllowed()) + local_param.SetWorstElemMeasure(global_param.GetWorstElemMeasure()) + local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary()) + local_param.SetNbThreads(global_param.GetNbThreads()) + else: + local_param.SetMaxSize(global_param.GetMaxSize()) + local_param.SetMinSize(global_param.GetMinSize()) + local_param.SetOptimize(global_param.GetOptimize()) + local_param.SetCheckOverlapping(global_param.GetCheckOverlapping()) + local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary()) + local_param.SetFineness(global_param.GetFineness()) + local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge()) + local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius()) + local_param.SetGrowthRate(global_param.GetGrowthRate()) + local_param.SetNbThreads(global_param.GetNbThreads()) + +class ParallelMesh(Mesh): + """ + Surcharge on Mesh for parallel computation of a mesh + """ + + def __init__(self, smeshpyD, geompyD, geom, param, nbThreads, name=0): + """ + Create a parallel mesh. + + Parameters: + geom: geometrical object for meshing + param: full mesh parameters + nbThreads: Number of threads for parallelisation. + name: the name for the new mesh. + + Returns: + an instance of class :class:`ParallelMesh`. + """ + + if not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object): + raise ValueError("geom argument must be a geometry") + + if not isinstance(param, NETGENPlugin._objref_NETGENPlugin_Hypothesis): + raise ValueError("param must come from NETGENPlugin") + + if nbThreads < 1: + raise ValueError("Number of threads must be stricly greater than 1") + + # Splitting geometry into 3D elements and all the 2D/1D into one compound + object_solids = geompyD.ExtractShapes(geom, geompyD.ShapeType["SOLID"], + True) + + solids = [] + isolid = 0 + for solid in object_solids: + isolid += 1 + geompyD.addToStudyInFather( geom, solid, 'Solid_{}'.format(isolid) ) + solids.append(solid) + + faces = [] + iface = 0 + for isolid, solid in enumerate(solids): + solid_faces = geompyD.ExtractShapes(solid, geompyD.ShapeType["FACE"], + True) + for face in solid_faces: + faces.append(face) + iface += 1 + geompyD.addToStudyInFather(solid, face, + 'Face_{}'.format(iface)) + + # Creating submesh for edges 1D/2D part + + all_faces = geompyD.MakeCompound(faces) + geompyD.addToStudy(all_faces, 'Compound_1') + all_faces = geompyD.MakeGlueEdges(all_faces, 1e-07) + all_faces = geompyD.MakeGlueFaces(all_faces, 1e-07) + geompyD.addToStudy(all_faces, 'global2D') + + super(ParallelMesh, self).__init__(smeshpyD, geompyD, geom, name) + + self.mesh.SetNbThreads(nbThreads) + + self.UseExistingSegments() + self.UseExistingFaces() + + algo2d = self.Triangle(geom=all_faces, algo="NETGEN_2D") + param2d = algo2d.Parameters() + + _copy_netgen_param(2, param2d, param) + + for solid_id, solid in enumerate(solids): + name = "Solid_{}".format(solid_id) + self.UseExistingSegments(geom=solid) + self.UseExistingFaces(geom=solid) + algo3d = self.Tetrahedron(geom=solid, algo="NETGEN_3D_Remote") + + param3d = algo3d.Parameters() + + _copy_netgen_param(3, param3d, param) + + pass # End of ParallelMesh + + class meshProxy(SMESH._objref_SMESH_Mesh): """ Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx index 40e8fbd82..886f72b63 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.cxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx @@ -716,7 +716,7 @@ void StdMeshers_Regular_1D::redistributeNearVertices (SMESH_Mesh & theM //============================================================================= /*! - * + * */ //============================================================================= bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, @@ -1164,7 +1164,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, //============================================================================= /*! - * + * */ //============================================================================= @@ -1338,7 +1338,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t //============================================================================= /*! - * + * */ //============================================================================= diff --git a/test/SMESH_ParallelCompute.py b/test/SMESH_ParallelCompute.py new file mode 100644 index 000000000..fccec1300 --- /dev/null +++ b/test/SMESH_ParallelCompute.py @@ -0,0 +1,133 @@ +# contains function to compute a mesh in parallel +from platform import java_ver +import sys +from tkinter import W +import salome + +import time + + +salome.salome_init() +import salome_notebook +notebook = salome_notebook.NoteBook() + +### +### GEOM component +### + +import GEOM +from salome.geom import geomBuilder +from salome.smesh import smeshBuilder +import math +import SALOMEDS + +import numpy as np + +geompy = geomBuilder.New() + +smesh = smeshBuilder.New() + + +def build_seq_mesh(nbox, boxsize, offset): + # Create 3D faces + boxes = [] + # First creating all the boxes + for i in range(nbox): + for j in range(nbox): + for k in range(nbox): + + x_orig = i*(boxsize+offset) + y_orig = j*(boxsize+offset) + z_orig = k*(boxsize+offset) + + tmp_box = geompy.MakeBoxDXDYDZ(boxsize, boxsize, boxsize) + + if not i == j == k == 0: + box = geompy.MakeTranslation(tmp_box, x_orig, + y_orig, z_orig) + else: + box = tmp_box + + geompy.addToStudy(box, 'box_{}:{}:{}'.format(i, j, k)) + + boxes.append(box) + + # Create fuse of all boxes + all_boxes = geompy.MakeCompound(boxes) + geompy.addToStudy(all_boxes, 'Compound_1') + + # Removing duplicates faces and edges + all_boxes = geompy.MakeGlueFaces(all_boxes, 1e-07) + geompy.addToStudy(all_boxes, 'Glued_Faces_1') + + all_boxes = geompy.MakeGlueEdges(all_boxes, 1e-07) + geompy.addToStudy(all_boxes, 'rubik_cube') + + + # Building sequetial mesh + print("Creating mesh") + all_box_mesh = smesh.Mesh(all_boxes, "seq_mesh") + + print("Adding algo") + algo3d = all_box_mesh.Tetrahedron(algo=smeshBuilder.NETGEN_1D2D3D) + + netgen_parameters = algo3d.Parameters() + netgen_parameters.SetMaxSize(34.641) + netgen_parameters.SetMinSize(0.141421) + netgen_parameters.SetOptimize(1) + netgen_parameters.SetCheckOverlapping(0) + netgen_parameters.SetCheckChartBoundary(0) + netgen_parameters.SetFineness(5) + netgen_parameters.SetNbSegPerEdge(16*(boxsize//100)) + netgen_parameters.SetNbSegPerRadius(1.5) + netgen_parameters.SetGrowthRate(0.15) + netgen_parameters.SetChordalError(-1) + netgen_parameters.SetChordalErrorEnabled(0) + netgen_parameters.SetUseSurfaceCurvature(1) + netgen_parameters.SetQuadAllowed(0) + netgen_parameters.SetCheckOverlapping(False) + netgen_parameters.SetNbThreads(2) + + return all_boxes, all_box_mesh, netgen_parameters + +def run_test(nbox=2, boxsize=100): + """ Run sequential mesh and parallel version of it + + nbox: NUmber of boxes + boxsize: Size of each box + """ + geom, seq_mesh, netgen_parameters = build_seq_mesh(nbox, boxsize, 0) + + par_mesh = smesh.ParallelMesh(geom, netgen_parameters, 6, name="par_mesh") + + start = time.monotonic() + is_done = seq_mesh.Compute() + assert is_done + stop = time.monotonic() + time_seq = stop-start + + start = time.monotonic() + is_done = par_mesh.Compute() + assert is_done + stop = time.monotonic() + time_par = stop-start + + print(" Tetrahedron: ", seq_mesh.NbTetras(), par_mesh.NbTetras()) + print(" Triangle: ", seq_mesh.NbTriangles(), par_mesh.NbTriangles()) + print(" edge: ", seq_mesh.NbEdges(), par_mesh.NbEdges()) + + assert par_mesh.NbTetras() > 0 + assert par_mesh.NbTriangles() > 0 + assert par_mesh.NbEdges() > 0 + + print("Time elapsed (seq, par): ", time_seq, time_par) + +def main(): + if sys.platform == "win32": + print("Test disabled on Windows") + return + nbox = 2 + boxsize = 100 + run_test(nbox, boxsize) + +main() diff --git a/test/netgen_runner.py b/test/netgen_runner.py new file mode 100644 index 000000000..76ec09d8b --- /dev/null +++ b/test/netgen_runner.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python +import sys +import salome + +salome.salome_init() + +from os import path +import tempfile +import subprocess + +import GEOM, SMESH, SALOMEDS + +from salome.geom import geomBuilder +from salome.smesh import smeshBuilder + +import math + +smesh = smeshBuilder.New() +geompy = geomBuilder.New() + +import medcoupling as mc + +def create_param_file(param_file): + """ Create a parameter file for runner """ + param = """1 +34.64 +0.14 +16 +0.15 +1.5 +0 +0 +1 +5 +1 +1 +-1 +3 +3 +0.2 +2 +1 +0 +0 +2 +2 +0 + +0 +0 +0""" + with open(param_file, "w") as ffile: + ffile.write(param) + + +def test_netgen3d(): + """ Test netgen3d mesher """ + # Building geometry + box = geompy.MakeBoxDXDYDZ(200, 200, 200) + + geompy.ExtractShapes(box, geompy.ShapeType["FACE"], True) + groupe_1 = geompy.CreateGroup(box, geompy.ShapeType["FACE"]) + geompy.UnionIDs(groupe_1, [3, 13, 23, 27, 31, 33]) + + [_, _, _, _, _, _, groupe_1] = geompy.GetExistingSubObjects(box, False) + + # Creating 2D mesh + netgen_2d_parameters_1 = smesh.CreateHypothesisByAverageLength( + 'NETGEN_Parameters_2D', 'NETGENEngine', 34.641, 0) + mesh_2d = smesh.Mesh(groupe_1, 'Maillage_1') + mesh_2d.AddHypothesis(groupe_1, netgen_2d_parameters_1) + mesh_2d.Triangle(algo=smeshBuilder.NETGEN_1D2D) + is_done = mesh_2d.Compute() + assert is_done + smesh.SetName(mesh_2d, 'Maillage_1') + + with tempfile.TemporaryDirectory() as tmp_dir: + mesh_file = path.join(tmp_dir, "mesh.med") + shape_file = path.join(tmp_dir, "shape.step") + param_file = path.join(tmp_dir, "param.txt") + output_mesh = path.join(tmp_dir, "mesh3D.med") + + print("Running in folder: ", tmp_dir) + create_param_file(param_file) + + mesh_2d.ExportMED(mesh_file, 0, 41, 1, mesh_2d, 1, [], '', -1, 1) + geompy.ExportSTEP(box, shape_file, GEOM.LU_METER) + + runner = path.join("${NETGENPLUGIN_ROOT_DIR}", + "bin", + "salome", + "NETGENPlugin_Runner") + + if sys.platform == 'win32': + runner += ".exe" + + cmd = "{runner} NETGEN3D {mesh_file} {shape_file} "\ + "{param_file} NONE NONE {output_mesh}"\ + .format(runner=runner, + mesh_file=mesh_file, + shape_file=shape_file, + param_file=param_file, + output_mesh=output_mesh) + print(cmd) + subprocess.check_call(cmd, shell=True) + + mesh_read = mc.ReadUMeshFromFile(output_mesh, "MESH", 0) + + nb_tetras = mesh_read.getNumberOfCellsWithType(mc.NORM_TETRA4) + nb_points = mesh_read.getNumberOfNodes() + + mesh_read = mc.ReadUMeshFromFile(output_mesh, "MESH", -1) + nb_triangles = mesh_read.getNumberOfCellsWithType(mc.NORM_TRI3) + + mesh_read = mc.ReadUMeshFromFile(output_mesh, "MESH", -2) + nb_segments = mesh_read.getNumberOfCellsWithType(mc.NORM_SEG2) + + print("Nb Tetras:", nb_tetras) + print("Nb Triangles:", nb_triangles) + print("Nb Segments:", nb_segments) + print("Nb Points:", nb_points) + + assert nb_points > 0 + assert nb_segments > 0 + assert nb_triangles > 0 + assert nb_tetras > 0 + +if __name__ == "__main__": + if sys.platform == "win32": + print("Disabled on windows") + sys.exit(0) + test_netgen3d() diff --git a/test/tests.set b/test/tests.set index 21491d807..0035933fe 100644 --- a/test/tests.set +++ b/test/tests.set @@ -64,6 +64,8 @@ SET(BAD_TESTS SMESH_test4.py SMESH_create_dual_mesh_adapt.py SMESH_create_dual_mesh_tpipe.py + netgen_runner.py + SMESH_ParallelCompute.py ) IF(NOT WIN32) LIST(APPEND BAD_TESTS