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

@ -91,6 +91,7 @@ SET(NETGENEngine_HEADERS
NETGENPlugin_Mesher.hxx
NETGENPlugin_Remesher_2D.hxx
NETGENPlugin_Defs.hxx
NETGENPlugin_Provider.hxx
)
# --- sources ---

View File

@ -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;
@ -361,6 +362,8 @@ class NETGEN_2D_Only_Algorithm(NETGEN_Algorithm):
# @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;

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>
@ -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

@ -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;
}

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;