Using provider for occgeom and nglib

This commit is contained in:
Yoann Audouin 2022-07-25 10:34:43 +02:00
parent 6fd7220e46
commit acbb35b4c3
5 changed files with 204 additions and 75 deletions

View File

@ -34,7 +34,7 @@ INCLUDE_DIRECTORIES(
)
# additional preprocessor / compiler flags
ADD_DEFINITIONS(
ADD_DEFINITIONS(
${OMNIORB_DEFINITIONS}
${OpenCASCADE_DEFINITIONS}
${BOOST_DEFINITIONS}
@ -70,27 +70,28 @@ SET(_link_LIBRARIES
# header files
SET(NETGENEngine_HEADERS
NETGENPlugin_NETGEN_3D.hxx
NETGENPlugin_NETGEN_3D_i.hxx
NETGENPlugin_NETGEN_2D.hxx
NETGENPlugin_NETGEN_2D_i.hxx
NETGENPlugin_NETGEN_2D3D.hxx
NETGENPlugin_NETGEN_2D3D_i.hxx
NETGENPlugin_NETGEN_2D_ONLY.hxx
NETGENPlugin_NETGEN_2D_ONLY_i.hxx
NETGENPlugin_Hypothesis.hxx
NETGENPlugin_Hypothesis_i.hxx
NETGENPlugin_Hypothesis_2D.hxx
NETGENPlugin_Hypothesis_2D_i.hxx
NETGENPlugin_Hypothesis_3D_i.hxx
NETGENPlugin_Hypothesis_2D_ONLY_i.hxx
NETGENPlugin_SimpleHypothesis_2D.hxx
NETGENPlugin_SimpleHypothesis_3D.hxx
NETGENPlugin_SimpleHypothesis_2D_i.hxx
NETGENPlugin_SimpleHypothesis_3D_i.hxx
NETGENPlugin_Mesher.hxx
NETGENPlugin_NETGEN_3D.hxx
NETGENPlugin_NETGEN_3D_i.hxx
NETGENPlugin_NETGEN_2D.hxx
NETGENPlugin_NETGEN_2D_i.hxx
NETGENPlugin_NETGEN_2D3D.hxx
NETGENPlugin_NETGEN_2D3D_i.hxx
NETGENPlugin_NETGEN_2D_ONLY.hxx
NETGENPlugin_NETGEN_2D_ONLY_i.hxx
NETGENPlugin_Hypothesis.hxx
NETGENPlugin_Hypothesis_i.hxx
NETGENPlugin_Hypothesis_2D.hxx
NETGENPlugin_Hypothesis_2D_i.hxx
NETGENPlugin_Hypothesis_3D_i.hxx
NETGENPlugin_Hypothesis_2D_ONLY_i.hxx
NETGENPlugin_SimpleHypothesis_2D.hxx
NETGENPlugin_SimpleHypothesis_3D.hxx
NETGENPlugin_SimpleHypothesis_2D_i.hxx
NETGENPlugin_SimpleHypothesis_3D_i.hxx
NETGENPlugin_Mesher.hxx
NETGENPlugin_Remesher_2D.hxx
NETGENPlugin_Defs.hxx
NETGENPlugin_Provider.hxx
)
# --- sources ---

View File

@ -40,19 +40,19 @@ NETGEN_VERSION_MAJOR = NETGENPlugin.NETGEN_VERSION_MAJOR
# Mesh algo type identifiers
#----------------------------
## Algorithm type: Netgen tetrahedron 3D algorithm, see NETGEN_3D_Algorithm
## Algorithm type: Netgen tetrahedron 3D algorithm, see NETGEN_3D_Algorithm
NETGEN_3D = "NETGEN_3D"
## Algorithm type: Netgen tetrahedron 1D-2D-3D algorithm, see NETGEN_1D2D3D_Algorithm
## Algorithm type: Netgen tetrahedron 1D-2D-3D algorithm, see NETGEN_1D2D3D_Algorithm
NETGEN_1D2D3D = "NETGEN_2D3D"
## Algorithm type: Netgen triangle 1D-2D algorithm, see NETGEN_1D2D_Algorithm
## Algorithm type: Netgen triangle 1D-2D algorithm, see NETGEN_1D2D_Algorithm
NETGEN_1D2D = "NETGEN_2D"
## Algorithm type: Netgen triangle 2D algorithm, see NETGEN_2D_Only_Algorithm
NETGEN_2D = "NETGEN_2D_ONLY"
## Algorithm type: Synonim of NETGEN_1D2D3D, see NETGEN_1D2D3D_Algorithm
## Algorithm type: Synonim of NETGEN_1D2D3D, see NETGEN_1D2D3D_Algorithm
NETGEN_FULL = NETGEN_1D2D3D
## Algorithm type: Synonim of NETGEN_3D, see NETGEN_3D_Algorithm
## Algorithm type: Synonim of NETGEN_3D, see NETGEN_3D_Algorithm
NETGEN = NETGEN_3D
## Algorithm type: Synonim of NETGEN_1D2D3D, see NETGEN_1D2D3D_Algorithm
## Algorithm type: Synonim of NETGEN_1D2D3D, see NETGEN_1D2D3D_Algorithm
FULL_NETGEN = NETGEN_FULL
#----------------------------
@ -190,7 +190,7 @@ class NETGEN_Algorithm(Mesh_Algorithm):
def SetLocalSizeOnShape(self, shape, size ):
self.Parameters().SetLocalSizeOnShape(shape, size)
pass
pass # end of NETGEN_Algorithm class
@ -310,7 +310,7 @@ class NETGEN_1D2D3D_Algorithm(NETGEN_Algorithm):
pass # end of NETGEN_1D2D3D_Algorithm class
## Triangle NETGEN 1D-2D algorithm.
## Triangle NETGEN 1D-2D algorithm.
#
# It can be created by calling smeshBuilder.Mesh.Triangle( smeshBuilder.NETGEN_1D2D, geom=0 )
#
@ -328,6 +328,7 @@ class NETGEN_1D2D_Algorithm(NETGEN_1D2D3D_Algorithm):
# @internal
docHelper = "Creates triangle 2D algorithm for faces"
## Private constructor.
# @param mesh parent mesh object algorithm is assigned to
# @param geom geometry (shape/sub-shape) algorithm is assigned to;
@ -360,7 +361,9 @@ class NETGEN_2D_Only_Algorithm(NETGEN_Algorithm):
## doc string of the method
# @internal
docHelper = "Creates triangle 2D algorithm for faces"
isDefault = True
## Private constructor.
# @param mesh parent mesh object algorithm is assigned to
# @param geom geometry (shape/sub-shape) algorithm is assigned to;
@ -388,7 +391,7 @@ class NETGEN_2D_Only_Algorithm(NETGEN_Algorithm):
def LengthFromEdges(self):
hyp = self.Hypothesis("LengthFromEdges", UseExisting=1, CompareMethod=self.CompareEqualHyp)
return hyp
## Sets @c UseSurfaceCurvature flag
# @param toUse new value of the @c UseSurfaceCurvature parameter (@c True by default)
def SetUseSurfaceCurvature(self, toUse=True):

View File

@ -25,6 +25,7 @@
#include "NETGENPlugin_Mesher.hxx"
#include "NETGENPlugin_Hypothesis_2D.hxx"
#include "NETGENPlugin_Provider.hxx"
#include <SMDS_MeshElement.hxx>
#include <SMDS_MeshNode.hxx>
@ -76,7 +77,7 @@ using namespace nglib;
//=============================================================================
/*!
*
*
*/
//=============================================================================
@ -85,7 +86,7 @@ NETGENPlugin_NETGEN_2D_ONLY::NETGENPlugin_NETGEN_2D_ONLY(int hypId,
: SMESH_2D_Algo(hypId, gen)
{
_name = "NETGEN_2D_ONLY";
_shapeType = (1 << TopAbs_FACE);// 1 bit /shape type
_onlyUnaryInput = false; // treat all FACEs at once
@ -103,7 +104,7 @@ NETGENPlugin_NETGEN_2D_ONLY::NETGENPlugin_NETGEN_2D_ONLY(int hypId,
//=============================================================================
/*!
*
*
*/
//=============================================================================
@ -114,7 +115,7 @@ NETGENPlugin_NETGEN_2D_ONLY::~NETGENPlugin_NETGEN_2D_ONLY()
//=============================================================================
/*!
*
*
*/
//=============================================================================
@ -128,6 +129,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::CheckHypothesis (SMESH_Mesh& aMesh,
_hypParameters = 0;
_progressByTic = -1;
const list<const SMESHDS_Hypothesis*>& hyps = GetUsedHypothesis(aMesh, aShape, false);
if (hyps.empty())
@ -226,6 +228,11 @@ bool NETGENPlugin_NETGEN_2D_ONLY::CheckHypothesis (SMESH_Mesh& aMesh,
bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape)
{
aMesh.Lock();
SMESH_Hypothesis::Hypothesis_Status hypStatus;
this->CheckHypothesis(aMesh, aShape, hypStatus);
aMesh.Unlock();
netgen::multithread.terminate = 0;
//netgen::multithread.task = "Surface meshing";
@ -233,12 +240,14 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
SMESH_MesherHelper helper(aMesh);
helper.SetElementsOnShape( true );
NETGENPlugin_NetgenLibWrapper ngLib;
ngLib._isComputeOk = false;
NETGENPlugin_NetgenLibWrapper *ngLib;
int id_ngLib = nglib_provider.take(&ngLib);
ngLib->_isComputeOk = false;
netgen::Mesh ngMeshNoLocSize;
netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib._ngMesh, & ngMeshNoLocSize };
netgen::OCCGeometry occgeoComm;
netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib->_ngMesh, & ngMeshNoLocSize };
netgen::OCCGeometry *occgeoComm;
int id_occgeoComm = occgeom_provider.take(&occgeoComm);
// min / max sizes are set as follows:
// if ( _hypParameters )
@ -252,7 +261,6 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
// else
// min = aMesher.GetDefaultMinSize()
// max = max segment len of a FACE
NETGENPlugin_Mesher aMesher( &aMesh, aShape, /*isVolume=*/false);
aMesher.SetParameters( _hypParameters ); // _hypParameters -> netgen::mparam
const bool toOptimize = _hypParameters ? _hypParameters->GetOptimize() : true;
@ -270,14 +278,14 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
if ( isCommonLocalSize ) // compute common local size in ngMeshes[0]
{
//list< SMESH_subMesh* > meshedSM[4]; --> all sub-shapes are added to occgeoComm
aMesher.PrepareOCCgeometry( occgeoComm, aShape, aMesh );//, meshedSM );
aMesher.PrepareOCCgeometry( *occgeoComm, aShape, aMesh );//, meshedSM );
// local size set at MESHCONST_ANALYSE step depends on
// minh, face_maxh, grading and curvaturesafety; find minh if not set by the user
if ( !_hypParameters || netgen::mparam.minh < DBL_MIN )
{
if ( !_hypParameters )
netgen::mparam.maxh = occgeoComm.GetBoundingBox().Diam() / 3.;
netgen::mparam.maxh = occgeoComm->GetBoundingBox().Diam() / 3.;
netgen::mparam.minh = aMesher.GetDefaultMinSize( aShape, netgen::mparam.maxh );
}
// set local size depending on curvature and NOT closeness of EDGEs
@ -288,15 +296,15 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
netgen::occparam.resthcloseedgeenable = false;
netgen::occparam.resthcloseedgefac = 1.0 + netgen::mparam.grading;
#endif
occgeoComm.face_maxh = netgen::mparam.maxh;
occgeoComm->face_maxh = netgen::mparam.maxh;
#ifdef NETGEN_V6
netgen::OCCParameters occparam;
netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0], netgen::mparam, occparam );
netgen::OCCSetLocalMeshSize( *occgeoComm, *ngMeshes[0], netgen::mparam, occparam );
#else
netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0] );
netgen::OCCSetLocalMeshSize( *occgeoComm, *ngMeshes[0] );
#endif
occgeoComm.emap.Clear();
occgeoComm.vmap.Clear();
occgeoComm->emap.Clear();
occgeoComm->vmap.Clear();
// set local size according to size of existing segments
TopTools_IndexedMapOfShape edgeMap;
@ -321,8 +329,8 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
}
// set local size defined on shapes
aMesher.SetLocalSize( occgeoComm, *ngMeshes[0] );
aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMeshes[0] );
aMesher.SetLocalSize( *occgeoComm, *ngMeshes[0] );
aMesher.SetLocalSizeForChordalError( *occgeoComm, *ngMeshes[0] );
try {
ngMeshes[0]->LoadLocalMeshSize( mparam.meshsizefilename );
} catch (NgException & ex) {
@ -330,7 +338,6 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
}
}
netgen::mparam.uselocalh = toOptimize; // restore as it is used at surface optimization
// ==================
// Loop on all FACEs
// ==================
@ -419,7 +426,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
netgen::mparam.maxh = edgeLength;
}
if ( netgen::mparam.maxh < DBL_MIN )
netgen::mparam.maxh = occgeoComm.GetBoundingBox().Diam();
netgen::mparam.maxh = occgeoComm->GetBoundingBox().Diam();
if ( !isCommonLocalSize )
{
@ -428,16 +435,17 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
}
// prepare occgeom
netgen::OCCGeometry occgeom;
occgeom.shape = F;
occgeom.fmap.Add( F );
occgeom.CalcBoundingBox();
occgeom.facemeshstatus.SetSize(1);
occgeom.facemeshstatus = 0;
occgeom.face_maxh_modified.SetSize(1);
occgeom.face_maxh_modified = 0;
occgeom.face_maxh.SetSize(1);
occgeom.face_maxh = netgen::mparam.maxh;
netgen::OCCGeometry *occgeom;
int id_occgeom = occgeom_provider.take(&occgeom);
occgeom->shape = F;
occgeom->fmap.Add( F );
occgeom->CalcBoundingBox();
occgeom->facemeshstatus.SetSize(1);
occgeom->facemeshstatus = 0;
occgeom->face_maxh_modified.SetSize(1);
occgeom->face_maxh_modified = 0;
occgeom->face_maxh.SetSize(1);
occgeom->face_maxh = netgen::mparam.maxh;
// -------------------------
// Fill netgen mesh
@ -460,11 +468,11 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
{
ngMesh->SetGlobalH ( mparam.maxh );
ngMesh->SetMinimalH( mparam.minh );
Box<3> bb = occgeom.GetBoundingBox();
Box<3> bb = occgeom->GetBoundingBox();
bb.Increase (bb.Diam()/10);
ngMesh->SetLocalH (bb.PMin(), bb.PMax(), mparam.grading);
aMesher.SetLocalSize( occgeom, *ngMesh );
aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMesh );
aMesher.SetLocalSize( *occgeom, *ngMesh );
aMesher.SetLocalSizeForChordalError( *occgeoComm, *ngMesh );
try {
ngMesh->LoadLocalMeshSize( mparam.meshsizefilename );
} catch (NgException & ex) {
@ -473,7 +481,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
}
nodeVec.clear();
faceErr = aMesher.AddSegmentsToMesh( *ngMesh, occgeom, wires, helper, nodeVec,
faceErr = aMesher.AddSegmentsToMesh( *ngMesh, *occgeom, wires, helper, nodeVec,
/*overrideMinH=*/!_hypParameters);
if ( faceErr && !faceErr->IsOK() )
break;
@ -491,9 +499,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
SMESH_Comment str;
try {
OCC_CATCH_SIGNALS;
err = ngLib.GenerateMesh(occgeom, startWith, endWith, ngMesh);
err = ngLib->GenerateMesh(*occgeom, startWith, endWith, ngMesh);
if ( netgen::multithread.terminate )
return false;
if ( err )
@ -515,7 +521,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
}
if ( err )
{
if ( aMesher.FixFaceMesh( occgeom, *ngMesh, 1 ))
if ( aMesher.FixFaceMesh( *occgeom, *ngMesh, 1 ))
break;
if ( iLoop == LOC_SIZE )
{
@ -546,7 +552,9 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
}
}
occgeom_provider.release(id_occgeoComm, true);
occgeom_provider.release(id_occgeom, true);
aMesh.Lock();
// ----------------------------------------------------
// Fill the SMESHDS with the generated nodes and faces
// ----------------------------------------------------
@ -596,6 +604,9 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
break;
} // two attempts
} // loop on FACEs
aMesh.Unlock();
nglib_provider.release(id_ngLib, true);
return true;
}

View File

@ -95,7 +95,7 @@ using namespace std;
//=============================================================================
/*!
*
*
*/
//=============================================================================
@ -119,7 +119,7 @@ NETGENPlugin_NETGEN_3D::NETGENPlugin_NETGEN_3D(int hypId, SMESH_Gen* gen)
//=============================================================================
/*!
*
*
*/
//=============================================================================
@ -129,7 +129,7 @@ NETGENPlugin_NETGEN_3D::~NETGENPlugin_NETGEN_3D()
//=============================================================================
/*!
*
*
*/
//=============================================================================
@ -544,7 +544,7 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh,
if ( ce && ce->HasBadElems() )
error( ce );
}
aMesh.Lock();
bool isOK = ( /*status == NG_OK &&*/ Netgen_NbOfTetra > 0 );// get whatever built
if ( isOK )
{
@ -576,6 +576,8 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh,
}
}
}
aMesh.Unlock();
return !err;
}
@ -641,7 +643,7 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh,
return error( COMPERR_BAD_INPUT_MESH, "Null element encounters");
if ( elem->NbCornerNodes() != 3 )
return error( COMPERR_BAD_INPUT_MESH, "Not triangle element encounters");
// add three nodes of triangle
for ( int iN = 0; iN < 3; ++iN )
{
@ -797,7 +799,7 @@ bool NETGENPlugin_NETGEN_3D::Evaluate(SMESH_Mesh& aMesh,
}
SMESH_subMesh *sm = aMesh.GetSubMesh(aShape);
aResMap.insert(std::make_pair(sm,aVec));
return true;
}

View File

@ -0,0 +1,112 @@
// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE
//
// 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 : NETGENPlugin_Provider.hxx
// Author : Yoann AUDOUIN (EDF)
// Project : SALOME
//
#include <iostream>
#include <thread>
#include <array>
#include <vector>
#include <unistd.h>
#include <mutex>
namespace nglib {
#include <nglib.h>
}
#ifndef OCCGEOMETRY
#define OCCGEOMETRY
#endif
#include <occgeom.hpp>
#include <meshing.hpp>
template<class T, int NDATA>
class ProviderPtr{
public:
ProviderPtr(){
for(int i=0;i<NDATA;i++){
this->_mydata[i] = nullptr;
this->_useddata[i] = false;
}
}
ProviderPtr(std::array<int, NDATA> is, std::array<double, NDATA> ds){
for(int i=0;i<NDATA;i++){
this->_mydata[i] = new T(is[i], ds[i]);
this->_useddata[i] = false;
}
}
int take(T** data){
this->_mymutex.lock();
*data = nullptr;
for(int i=0;i<NDATA;i++){
if(!this->_useddata[i]){
if (this->_mydata[i] == nullptr)
this->_mydata[i] = new T();
this->_useddata[i] = true;
*data = this->_mydata[i];
this->_mymutex.unlock();
return i;
}
}
this->_mymutex.unlock();
return -1;
};
bool release(int i, bool clean){
this->_mymutex.lock();
if(clean){
delete this->_mydata[i];
this->_mydata[i] = nullptr;
}
this->_useddata[i] = false;
this->_mymutex.unlock();
return true;
};
void dump(){
std::cout << "Dumping provider:" << std::endl;
for(int i=0;i<NDATA;i++){
std::cout << " - " << i << " used: " << this->_useddata[i] << std::endl;
std::cout << " - adress: " << this->_mydata[i] << std::endl;
if (this->_mydata[i] != nullptr)
std::cout << " - i: " << this->_mydata[i]->i << " d: " << this->_mydata[i]->d << std::endl;
}
};
private:
std::array<T*, NDATA> _mydata;
std::array<bool, NDATA> _useddata;
std::mutex _mymutex;
};
ProviderPtr<netgen::OCCGeometry, 4> occgeom_provider;
ProviderPtr<NETGENPlugin_NetgenLibWrapper, 2> nglib_provider;