0020676: EDF 1212 GEOM: Partition operation creates vertices which causes mesh computation to fail with netgen
* Solve problem with internal edges and faces
This commit is contained in:
parent
6dbabf8a00
commit
1ebad126db
File diff suppressed because it is too large
Load Diff
@ -30,8 +30,15 @@
|
|||||||
|
|
||||||
#include "NETGENPlugin_Defs.hxx"
|
#include "NETGENPlugin_Defs.hxx"
|
||||||
#include "StdMeshers_FaceSide.hxx"
|
#include "StdMeshers_FaceSide.hxx"
|
||||||
|
#include "SMDS_MeshElement.hxx"
|
||||||
|
|
||||||
|
namespace nglib {
|
||||||
|
#include <nglib.h>
|
||||||
|
}
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
class SMESH_Mesh;
|
class SMESH_Mesh;
|
||||||
class SMESH_Comment;
|
class SMESH_Comment;
|
||||||
@ -40,6 +47,7 @@ class TopoDS_Shape;
|
|||||||
class TopTools_DataMapOfShapeShape;
|
class TopTools_DataMapOfShapeShape;
|
||||||
class NETGENPlugin_Hypothesis;
|
class NETGENPlugin_Hypothesis;
|
||||||
class NETGENPlugin_SimpleHypothesis_2D;
|
class NETGENPlugin_SimpleHypothesis_2D;
|
||||||
|
class NETGENPlugin_Internals;
|
||||||
namespace netgen {
|
namespace netgen {
|
||||||
class OCCGeometry;
|
class OCCGeometry;
|
||||||
class Mesh;
|
class Mesh;
|
||||||
@ -81,19 +89,20 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Mesher
|
|||||||
const TopoDS_Shape& shape,
|
const TopoDS_Shape& shape,
|
||||||
SMESH_Mesh& mesh,
|
SMESH_Mesh& mesh,
|
||||||
std::list< SMESH_subMesh* > * meshedSM=0,
|
std::list< SMESH_subMesh* > * meshedSM=0,
|
||||||
TopTools_DataMapOfShapeShape* internalE2F=0);
|
NETGENPlugin_Internals* internalShapes=0);
|
||||||
|
|
||||||
static int FillSMesh(const netgen::OCCGeometry& occgeom,
|
static int FillSMesh(const netgen::OCCGeometry& occgeom,
|
||||||
const netgen::Mesh& ngMesh,
|
const netgen::Mesh& ngMesh,
|
||||||
const NETGENPlugin_ngMeshInfo& initState,
|
const NETGENPlugin_ngMeshInfo& initState,
|
||||||
SMESH_Mesh& sMesh,
|
SMESH_Mesh& sMesh,
|
||||||
std::vector<SMDS_MeshNode*>& nodeVec,
|
std::vector<const SMDS_MeshNode*>& nodeVec,
|
||||||
SMESH_Comment& comment);
|
SMESH_Comment& comment);
|
||||||
|
|
||||||
bool fillNgMesh(netgen::OCCGeometry& occgeom,
|
bool fillNgMesh(netgen::OCCGeometry& occgeom,
|
||||||
netgen::Mesh& ngMesh,
|
netgen::Mesh& ngMesh,
|
||||||
std::vector<SMDS_MeshNode*>& nodeVec,
|
std::vector<const SMDS_MeshNode*>& nodeVec,
|
||||||
const std::list< SMESH_subMesh* > & meshedSM);
|
const std::list< SMESH_subMesh* > & meshedSM,
|
||||||
|
NETGENPlugin_Internals* internalShapes=0);
|
||||||
|
|
||||||
void defaultParameters();
|
void defaultParameters();
|
||||||
|
|
||||||
@ -111,4 +120,72 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Mesher
|
|||||||
std::map< int, std::pair<int,int> > _faceDescriptors;
|
std::map< int, std::pair<int,int> > _faceDescriptors;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Container of info needed to solve problems with internal shapes.
|
||||||
|
*
|
||||||
|
* Issue 0020676. It is made up as a class to be ready to extract from NETGEN
|
||||||
|
* and put in SMESH as soon as the same solution is needed somewhere else.
|
||||||
|
* The approach is to precompute internal edges in 2D and internal faces in 3D
|
||||||
|
* and put their mesh correctly (twice) into netgen mesh.
|
||||||
|
* In 2D, this class finds internal edges in faces and their vertices.
|
||||||
|
* In 3D, it additionally finds internal faces, their edges shared with other faces,
|
||||||
|
* and their vertices shared by several internal edges. Nodes built on the found
|
||||||
|
* shapes and mesh faces built on the found internal faces are to be doubled in
|
||||||
|
* netgen mesh to emulate a "crack"
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
class NETGENPLUGIN_EXPORT NETGENPlugin_Internals
|
||||||
|
{
|
||||||
|
SMESH_Mesh& _mesh;
|
||||||
|
bool _is3D;
|
||||||
|
//2D
|
||||||
|
std::map<int,int> _ev2face; //!< edges and vertices in faces where they are TopAbs_INTERNAL
|
||||||
|
// 3D
|
||||||
|
std::set<int> _intShapes;
|
||||||
|
std::set<int> _borderFaces; //!< non-intrnal faces sharing the internal edge
|
||||||
|
|
||||||
|
public:
|
||||||
|
NETGENPlugin_Internals( SMESH_Mesh& mesh, const TopoDS_Shape& shape, bool is3D );
|
||||||
|
|
||||||
|
bool isShapeToPrecompute(const TopoDS_Shape& s);
|
||||||
|
|
||||||
|
// 2D
|
||||||
|
bool hasInternalEdges() const { return !_ev2face.empty(); }
|
||||||
|
bool isInternalEdge(int id ) const { return _ev2face.count( id ); }
|
||||||
|
bool isInternalVertex(int id ) const { return _ev2face.count( id ); }
|
||||||
|
const std::map<int,int>& getEdgesAndVerticesWithFaces() const { return _ev2face; }
|
||||||
|
void getInternalEdges( TopTools_IndexedMapOfShape& fmap,
|
||||||
|
TopTools_IndexedMapOfShape& emap,
|
||||||
|
TopTools_IndexedMapOfShape& vmap,
|
||||||
|
list< SMESH_subMesh* >& smToPrecompute);
|
||||||
|
|
||||||
|
// 3D
|
||||||
|
bool hasInternalFaces() const { return !_intShapes.empty(); }
|
||||||
|
bool isInternalShape(int id ) const { return _intShapes.count( id ); }
|
||||||
|
void findBorderElements( std::set< const SMDS_MeshElement*, TIDCompare > & borderElems );
|
||||||
|
bool isBorderFace(int faceID ) const { return _borderFaces.count( faceID ); }
|
||||||
|
void getInternalFaces( TopTools_IndexedMapOfShape& fmap,
|
||||||
|
TopTools_IndexedMapOfShape& emap,
|
||||||
|
list< SMESH_subMesh* >& facesSM,
|
||||||
|
list< SMESH_subMesh* >& boundarySM);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief It correctly initializes netgen library at constructor and
|
||||||
|
* correctly finishes using netgen library at destructor
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
struct NETGENPLUGIN_EXPORT NETGENPlugin_NetgenLibWrapper
|
||||||
|
{
|
||||||
|
nglib::Ng_Mesh * _ngMesh;
|
||||||
|
NETGENPlugin_NetgenLibWrapper();
|
||||||
|
~NETGENPlugin_NetgenLibWrapper();
|
||||||
|
void setMesh( nglib::Ng_Mesh* mesh );
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -174,6 +174,7 @@ static TError AddSegmentsToMesh(netgen::Mesh& ngMesh,
|
|||||||
// Check wires and count nodes
|
// Check wires and count nodes
|
||||||
// ----------------------------
|
// ----------------------------
|
||||||
int nbNodes = 0;
|
int nbNodes = 0;
|
||||||
|
double totalLength = 0;
|
||||||
for ( int iW = 0; iW < wires.size(); ++iW )
|
for ( int iW = 0; iW < wires.size(); ++iW )
|
||||||
{
|
{
|
||||||
StdMeshers_FaceSidePtr wire = wires[ iW ];
|
StdMeshers_FaceSidePtr wire = wires[ iW ];
|
||||||
@ -187,7 +188,8 @@ static TError AddSegmentsToMesh(netgen::Mesh& ngMesh,
|
|||||||
(new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH,
|
(new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH,
|
||||||
SMESH_Comment("Unexpected nb of points on wire ") << iW
|
SMESH_Comment("Unexpected nb of points on wire ") << iW
|
||||||
<< ": " << uvPtVec.size()<<" != "<<wire->NbPoints()));
|
<< ": " << uvPtVec.size()<<" != "<<wire->NbPoints()));
|
||||||
nbNodes += wire->NbPoints();
|
nbNodes += wire->NbPoints();
|
||||||
|
totalLength += wire->Length();
|
||||||
}
|
}
|
||||||
nodeVec.reserve( nbNodes );
|
nodeVec.reserve( nbNodes );
|
||||||
|
|
||||||
@ -200,7 +202,8 @@ static TError AddSegmentsToMesh(netgen::Mesh& ngMesh,
|
|||||||
// ngMesh.SetLocalH (bb.PMin(), bb.PMax(), 0.5); // set grading
|
// ngMesh.SetLocalH (bb.PMin(), bb.PMax(), 0.5); // set grading
|
||||||
|
|
||||||
const int faceID = 1, solidID = 0;
|
const int faceID = 1, solidID = 0;
|
||||||
ngMesh.AddFaceDescriptor (FaceDescriptor(faceID, solidID, solidID, 0));
|
if ( ngMesh.GetNFD() < 1 )
|
||||||
|
ngMesh.AddFaceDescriptor (FaceDescriptor(faceID, solidID, solidID, 0));
|
||||||
|
|
||||||
for ( int iW = 0; iW < wires.size(); ++iW )
|
for ( int iW = 0; iW < wires.size(); ++iW )
|
||||||
{
|
{
|
||||||
@ -231,8 +234,8 @@ static TError AddSegmentsToMesh(netgen::Mesh& ngMesh,
|
|||||||
Segment seg;
|
Segment seg;
|
||||||
|
|
||||||
#ifdef NETGEN_NEW
|
#ifdef NETGEN_NEW
|
||||||
seg.pnums[0] = ngMesh.GetNP(); // ng node id
|
seg.pnums[0] = ngMesh.GetNP(); // ng node id
|
||||||
seg.pnums[1] = seg.pnums[0] + 1; // ng node id
|
seg.pnums[1] = seg.pnums[0] + 1; // ng node id
|
||||||
#else
|
#else
|
||||||
seg.p1 = ngMesh.GetNP(); // ng node id
|
seg.p1 = ngMesh.GetNP(); // ng node id
|
||||||
seg.p2 = seg.p1 + 1; // ng node id
|
seg.p2 = seg.p1 + 1; // ng node id
|
||||||
@ -313,7 +316,71 @@ static TError AddSegmentsToMesh(netgen::Mesh& ngMesh,
|
|||||||
|
|
||||||
} // loop on wires of a face
|
} // loop on wires of a face
|
||||||
|
|
||||||
ngMesh.CalcSurfacesOfNode();
|
// add a segment instead of internal vertex
|
||||||
|
// const TopoDS_Face& face = TopoDS::Face( helper.GetSubShape() );
|
||||||
|
// for ( TopoDS_Iterator sh (face); sh.More(); sh.Next())
|
||||||
|
// {
|
||||||
|
// if ( sh.Value().ShapeType() != TopAbs_VERTEX ) continue;
|
||||||
|
|
||||||
|
// const TopoDS_Vertex V = TopoDS::Vertex( sh.Value() );
|
||||||
|
// SMESH_subMesh* sm = helper.GetMesh()->GetSubMesh( V );
|
||||||
|
// sm->ComputeStateEngine( SMESH_subMesh::COMPUTE );
|
||||||
|
// const SMDS_MeshNode * nV = SMESH_Algo::VertexNode( V, helper.GetMeshDS() );
|
||||||
|
// if ( !nV ) continue;
|
||||||
|
// double segLen = totalLength / ngMesh.GetNSeg() / 2;
|
||||||
|
// bool uvOK = false;
|
||||||
|
// gp_XY uvV = helper.GetNodeUV( face, nV, 0, &uvOK );
|
||||||
|
// if ( !uvOK ) helper.CheckNodeUV( face, nV, uvV, BRep_Tool::Tolerance( V ),/*force=*/true);
|
||||||
|
// gp_XY uvP( uvV.X() + segLen, uvV.Y() );
|
||||||
|
// TopLoc_Location loc;
|
||||||
|
// Handle(Geom_Surface) surf = BRep_Tool::Surface(face,loc);
|
||||||
|
// gp_Pnt P = surf->Value( uvP.X(), uvP.Y() ).Transformed( loc );
|
||||||
|
|
||||||
|
// MeshPoint mpV( Point<3> (nV->X(), nV->Y(), nV->Z()) );
|
||||||
|
// MeshPoint mpP( Point<3> (P.X(), P.Y(), P.Z()));
|
||||||
|
|
||||||
|
// ngMesh.AddPoint ( mpV, 1, EDGEPOINT );
|
||||||
|
// ngMesh.AddPoint ( mpP, 1, EDGEPOINT );
|
||||||
|
|
||||||
|
// nodeVec.push_back( nV );
|
||||||
|
|
||||||
|
// // Add the segment
|
||||||
|
// Segment seg;
|
||||||
|
|
||||||
|
// #ifdef NETGEN_NEW
|
||||||
|
// seg.pnums[0] = ngMesh.GetNP()-1; // ng node id
|
||||||
|
// seg.pnums[1] = ngMesh.GetNP(); // ng node id
|
||||||
|
// #else
|
||||||
|
// seg.p1 = ngMesh.GetNP()-1; // ng node id
|
||||||
|
// seg.p2 = ngMesh.GetNP(); // ng node id
|
||||||
|
// #endif
|
||||||
|
// seg.edgenr = ngMesh.GetNSeg() + 1;// segment id
|
||||||
|
// seg.si = faceID; // = geom.fmap.FindIndex (face);
|
||||||
|
|
||||||
|
// seg.epgeominfo[ 0 ].dist = 0; // param on curve
|
||||||
|
// seg.epgeominfo[ 0 ].u = uvV.X();
|
||||||
|
// seg.epgeominfo[ 0 ].v = uvV.Y();
|
||||||
|
// seg.epgeominfo[ 1 ].dist = segLen; // param on curve
|
||||||
|
// seg.epgeominfo[ 1 ].u = uvP.X();
|
||||||
|
// seg.epgeominfo[ 1 ].v = uvP.Y();
|
||||||
|
|
||||||
|
// seg.epgeominfo[ 0 ].edgenr = 10; // = geom.emap.FindIndex(edge);
|
||||||
|
// seg.epgeominfo[ 1 ].edgenr = 10; // = geom.emap.FindIndex(edge);
|
||||||
|
|
||||||
|
// ngMesh.AddSegment (seg);
|
||||||
|
|
||||||
|
// // add reverse segment
|
||||||
|
// #ifdef NETGEN_NEW
|
||||||
|
// swap (seg.pnums[0], seg.pnums[1]);
|
||||||
|
// #else
|
||||||
|
// swap (seg.p1, seg.p2);
|
||||||
|
// #endif
|
||||||
|
// swap( seg.epgeominfo[0], seg.epgeominfo[1] );
|
||||||
|
// seg.edgenr = ngMesh.GetNSeg() + 1; // segment id
|
||||||
|
// ngMesh.AddSegment (seg);
|
||||||
|
// }
|
||||||
|
|
||||||
|
ngMesh.CalcSurfacesOfNode();
|
||||||
|
|
||||||
return TError();
|
return TError();
|
||||||
}
|
}
|
||||||
@ -356,8 +423,8 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
|
|||||||
// Make input netgen mesh
|
// Make input netgen mesh
|
||||||
// -------------------------
|
// -------------------------
|
||||||
|
|
||||||
Ng_Init();
|
NETGENPlugin_NetgenLibWrapper ngLib;
|
||||||
netgen::Mesh * ngMesh = new netgen::Mesh ();
|
netgen::Mesh * ngMesh = (netgen::Mesh*) ngLib._ngMesh;
|
||||||
|
|
||||||
netgen::OCCGeometry occgeo;
|
netgen::OCCGeometry occgeo;
|
||||||
NETGENPlugin_Mesher::PrepareOCCgeometry( occgeo, F, aMesh );
|
NETGENPlugin_Mesher::PrepareOCCgeometry( occgeo, F, aMesh );
|
||||||
@ -366,10 +433,8 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
|
|||||||
|
|
||||||
vector< const SMDS_MeshNode* > nodeVec;
|
vector< const SMDS_MeshNode* > nodeVec;
|
||||||
problem = AddSegmentsToMesh( *ngMesh, occgeo, wires, helper, nodeVec );
|
problem = AddSegmentsToMesh( *ngMesh, occgeo, wires, helper, nodeVec );
|
||||||
if ( problem && !problem->IsOK() ) {
|
if ( problem && !problem->IsOK() )
|
||||||
delete ngMesh; Ng_Exit();
|
|
||||||
return error( problem );
|
return error( problem );
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
// compute edge length
|
// compute edge length
|
||||||
@ -480,11 +545,6 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
|
|||||||
face = helper.AddFace(nodes[0],nodes[1],nodes[2],nodes[3]);
|
face = helper.AddFace(nodes[0],nodes[1],nodes[2],nodes[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ng_DeleteMesh((nglib::Ng_Mesh*)ngMesh);
|
|
||||||
Ng_Exit();
|
|
||||||
|
|
||||||
NETGENPlugin_Mesher::RemoveTmpFiles();
|
|
||||||
|
|
||||||
return !err;
|
return !err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,25 +29,9 @@
|
|||||||
#include "SMESH_2D_Algo.hxx"
|
#include "SMESH_2D_Algo.hxx"
|
||||||
#include "SMESH_Mesh.hxx"
|
#include "SMESH_Mesh.hxx"
|
||||||
|
|
||||||
/*#define OCCGEOMETRY
|
|
||||||
#include <occgeom.hpp>
|
|
||||||
#include <meshing.hpp>//amv*/
|
|
||||||
|
|
||||||
class StdMeshers_MaxElementArea;
|
class StdMeshers_MaxElementArea;
|
||||||
class StdMeshers_LengthFromEdges;
|
class StdMeshers_LengthFromEdges;
|
||||||
class StdMeshers_QuadranglePreference;
|
class StdMeshers_QuadranglePreference;
|
||||||
//class NETGENPlugin_Hypothesis;
|
|
||||||
|
|
||||||
/*namespace netgen {
|
|
||||||
class OCCGeometry;
|
|
||||||
}*/
|
|
||||||
/*namespace netgen {
|
|
||||||
class OCCGeometry;
|
|
||||||
extern int OCCGenerateMesh (OCCGeometry&, Mesh*&, int, int, char*);
|
|
||||||
extern MeshingParameters mparam;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
//using namespace netgen;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Mesher generating 2D elements on a geometrical face taking
|
* \brief Mesher generating 2D elements on a geometrical face taking
|
||||||
|
@ -151,158 +151,6 @@ bool NETGENPlugin_NETGEN_3D::CheckHypothesis
|
|||||||
return isOk;
|
return isOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
//================================================================================
|
|
||||||
/*!
|
|
||||||
* \brief It correctly initializes netgen library at constructor and
|
|
||||||
* correctly finishes using netgen library at destructor
|
|
||||||
*/
|
|
||||||
//================================================================================
|
|
||||||
|
|
||||||
struct TNetgenLibWrapper
|
|
||||||
{
|
|
||||||
Ng_Mesh* _ngMesh;
|
|
||||||
TNetgenLibWrapper()
|
|
||||||
{
|
|
||||||
Ng_Init();
|
|
||||||
_ngMesh = Ng_NewMesh();
|
|
||||||
}
|
|
||||||
~TNetgenLibWrapper()
|
|
||||||
{
|
|
||||||
Ng_DeleteMesh( _ngMesh );
|
|
||||||
Ng_Exit();
|
|
||||||
NETGENPlugin_Mesher::RemoveTmpFiles();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//================================================================================
|
|
||||||
/*!
|
|
||||||
* \brief Find mesh faces on non-internal geom faces sharing internal edge
|
|
||||||
* some nodes of which are to be doubled to make the second border of the "crack"
|
|
||||||
*/
|
|
||||||
//================================================================================
|
|
||||||
|
|
||||||
void findBorders( const set<int>& internalShapeIds,
|
|
||||||
SMESH_MesherHelper& helper,
|
|
||||||
TIDSortedElemSet & borderElems,
|
|
||||||
set<int> & borderFaceIds )
|
|
||||||
{
|
|
||||||
SMESH_Mesh* mesh = helper.GetMesh();
|
|
||||||
SMESHDS_Mesh* meshDS = helper.GetMeshDS();
|
|
||||||
|
|
||||||
// loop on internal geom edges
|
|
||||||
set<int>::const_iterator intShapeId = internalShapeIds.begin();
|
|
||||||
for ( ; intShapeId != internalShapeIds.end(); ++intShapeId )
|
|
||||||
{
|
|
||||||
const TopoDS_Shape& s = meshDS->IndexToShape( *intShapeId );
|
|
||||||
if ( s.ShapeType() != TopAbs_EDGE ) continue;
|
|
||||||
|
|
||||||
// get internal and non-internal geom faces sharing the internal edge <s>
|
|
||||||
int intFace = 0;
|
|
||||||
set<int>::iterator bordFace = borderFaceIds.end();
|
|
||||||
TopTools_ListIteratorOfListOfShape ancIt( mesh->GetAncestors( s ));
|
|
||||||
for ( ; ancIt.More(); ancIt.Next() )
|
|
||||||
{
|
|
||||||
if ( ancIt.Value().ShapeType() != TopAbs_FACE ) continue;
|
|
||||||
int faceID = meshDS->ShapeToIndex( ancIt.Value() );
|
|
||||||
if ( internalShapeIds.count( faceID ))
|
|
||||||
intFace = faceID;
|
|
||||||
else
|
|
||||||
bordFace = borderFaceIds.insert( faceID ).first;
|
|
||||||
}
|
|
||||||
if ( bordFace == borderFaceIds.end() || !intFace ) continue;
|
|
||||||
|
|
||||||
// get all links of mesh faces on internal geom face sharing nodes on edge <s>
|
|
||||||
set< SMESH_OrientedLink > links; //!< links of faces on internal geom face
|
|
||||||
TIDSortedElemSet suspectFaces; //!< mesh faces on border geom faces
|
|
||||||
SMESHDS_SubMesh* intFaceSM = meshDS->MeshElements( intFace );
|
|
||||||
if ( !intFaceSM || intFaceSM->NbElements() == 0 ) continue;
|
|
||||||
SMESH_subMeshIteratorPtr smIt = mesh->GetSubMesh( s )->getDependsOnIterator(true,true);
|
|
||||||
while ( smIt->more() )
|
|
||||||
{
|
|
||||||
SMESHDS_SubMesh* sm = smIt->next()->GetSubMeshDS();
|
|
||||||
if ( !sm ) continue;
|
|
||||||
SMDS_NodeIteratorPtr nIt = sm->GetNodes();
|
|
||||||
while ( nIt->more() )
|
|
||||||
{
|
|
||||||
const SMDS_MeshNode* nOnEdge = nIt->next();
|
|
||||||
SMDS_ElemIteratorPtr fIt = nOnEdge->GetInverseElementIterator(SMDSAbs_Face);
|
|
||||||
while ( fIt->more() )
|
|
||||||
{
|
|
||||||
const SMDS_MeshElement* f = fIt->next();
|
|
||||||
if ( intFaceSM->Contains( f ))
|
|
||||||
{
|
|
||||||
int nbNodes = f->NbNodes() / ( f->IsQuadratic() ? 2 : 1 );
|
|
||||||
for ( int i = 0; i < nbNodes; ++i )
|
|
||||||
links.insert( SMESH_OrientedLink( f->GetNode(i), f->GetNode((i+1)%nbNodes)));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
suspectFaces.insert( f );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// <suspectFaces> having link with same orientation as mesh faces on
|
|
||||||
// the internal geom face are <borderElems>.
|
|
||||||
// Some of them have only one node on edge s, we collect them to decide
|
|
||||||
// later by links of found <borderElems>
|
|
||||||
TIDSortedElemSet posponedFaces;
|
|
||||||
set< SMESH_OrientedLink > borderLinks;
|
|
||||||
TIDSortedElemSet::iterator fIt = suspectFaces.begin();
|
|
||||||
for ( ; fIt != suspectFaces.end(); ++fIt )
|
|
||||||
{
|
|
||||||
const SMDS_MeshElement* f = *fIt;
|
|
||||||
bool linkFound = false, isBorder = false;
|
|
||||||
list< SMESH_OrientedLink > faceLinks;
|
|
||||||
int nbNodes = f->NbNodes() / ( f->IsQuadratic() ? 2 : 1 );
|
|
||||||
for ( int i = 0; i < nbNodes; ++i )
|
|
||||||
{
|
|
||||||
SMESH_OrientedLink link( f->GetNode(i), f->GetNode((i+1)%nbNodes));
|
|
||||||
faceLinks.push_back( link );
|
|
||||||
if ( !linkFound )
|
|
||||||
{
|
|
||||||
set< SMESH_OrientedLink >::iterator foundLink = links.find( link );
|
|
||||||
if ( foundLink != links.end() )
|
|
||||||
{
|
|
||||||
linkFound= true;
|
|
||||||
isBorder = ( foundLink->_reversed == link._reversed );
|
|
||||||
if ( !isBorder ) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( isBorder )
|
|
||||||
{
|
|
||||||
borderElems.insert( f );
|
|
||||||
borderLinks.insert( faceLinks.begin(), faceLinks.end() );
|
|
||||||
}
|
|
||||||
else if ( !linkFound )
|
|
||||||
{
|
|
||||||
posponedFaces.insert( f );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// decide on posponedFaces
|
|
||||||
for ( fIt = posponedFaces.begin(); fIt != posponedFaces.end(); ++fIt )
|
|
||||||
{
|
|
||||||
const SMDS_MeshElement* f = *fIt;
|
|
||||||
int nbNodes = f->NbNodes() / ( f->IsQuadratic() ? 2 : 1 );
|
|
||||||
for ( int i = 0; i < nbNodes; ++i )
|
|
||||||
{
|
|
||||||
SMESH_OrientedLink link( f->GetNode(i), f->GetNode((i+1)%nbNodes));
|
|
||||||
set< SMESH_OrientedLink >::iterator foundLink = borderLinks.find( link );
|
|
||||||
if ( foundLink != borderLinks.end() )
|
|
||||||
{
|
|
||||||
if ( foundLink->_reversed != link._reversed )
|
|
||||||
borderElems.insert( f );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
/*!
|
/*!
|
||||||
*Here we are going to use the NETGEN mesher
|
*Here we are going to use the NETGEN mesher
|
||||||
@ -328,7 +176,7 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh,
|
|||||||
int Netgen_triangle[3];
|
int Netgen_triangle[3];
|
||||||
int Netgen_tetrahedron[4];
|
int Netgen_tetrahedron[4];
|
||||||
|
|
||||||
TNetgenLibWrapper ngLib;
|
NETGENPlugin_NetgenLibWrapper ngLib;
|
||||||
Ng_Mesh * Netgen_mesh = ngLib._ngMesh;
|
Ng_Mesh * Netgen_mesh = ngLib._ngMesh;
|
||||||
|
|
||||||
// maps of 1) ordinary nodes and 2) doubled nodes on internal shapes
|
// maps of 1) ordinary nodes and 2) doubled nodes on internal shapes
|
||||||
@ -342,60 +190,17 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh,
|
|||||||
SMESH::Controls::Area areaControl;
|
SMESH::Controls::Area areaControl;
|
||||||
SMESH::Controls::TSequenceOfXYZ nodesCoords;
|
SMESH::Controls::TSequenceOfXYZ nodesCoords;
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
|
||||||
// Issue 0020676 (StudyFiss_bugNetgen3D.hdf). Pb with internal face.
|
// Issue 0020676 (StudyFiss_bugNetgen3D.hdf). Pb with internal face.
|
||||||
// Find internal geom faces, edges and vertices.
|
// Find internal geom faces, edges and vertices.
|
||||||
// Nodes and faces built on the found internal shapes
|
// Nodes and faces built on the found internal shapes
|
||||||
// will be doubled in Netgen input to make two borders of the "crack".
|
// will be doubled in Netgen input to make two borders of the "crack".
|
||||||
// --------------------------------------------------------------------
|
|
||||||
|
|
||||||
set<int> internalShapeIds;
|
NETGENPlugin_Internals internals( aMesh, aShape, /*is3D=*/true );
|
||||||
set<int> borderFaceIds; //!< non-internal geom faces sharing internal edge
|
|
||||||
|
|
||||||
// mesh faces on <borderFaceIds>, having nodes on internal edge that are
|
// mesh faces on non-internal geom faces sharing internal edge, whose some nodes
|
||||||
// to be replaced by doubled nodes
|
// are on internal edge and are to be replaced by doubled nodes
|
||||||
TIDSortedElemSet borderElems;
|
TIDSortedElemSet borderElems;
|
||||||
|
internals.findBorderElements( borderElems );
|
||||||
// find "internal" faces and edges
|
|
||||||
TopExp_Explorer exFa(aShape,TopAbs_FACE), exEd, exVe;
|
|
||||||
for ( ; exFa.More(); exFa.Next())
|
|
||||||
{
|
|
||||||
if ( exFa.Current().Orientation() == TopAbs_INTERNAL )
|
|
||||||
{
|
|
||||||
internalShapeIds.insert( meshDS->ShapeToIndex( exFa.Current() ));
|
|
||||||
for ( exEd.Init( exFa.Current(), TopAbs_EDGE ); exEd.More(); exEd.Next())
|
|
||||||
if ( helper.NbAncestors( exEd.Current(), aMesh, TopAbs_FACE ) > 1 )
|
|
||||||
internalShapeIds.insert( meshDS->ShapeToIndex( exEd.Current() ));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( !internalShapeIds.empty() )
|
|
||||||
{
|
|
||||||
// find internal vertices,
|
|
||||||
// we consider vertex internal if it is shared by more than one internal edge
|
|
||||||
TopTools_ListIteratorOfListOfShape ancIt;
|
|
||||||
set<int>::iterator intShapeId = internalShapeIds.begin();
|
|
||||||
for ( ; intShapeId != internalShapeIds.end(); ++intShapeId )
|
|
||||||
{
|
|
||||||
const TopoDS_Shape& s = meshDS->IndexToShape( *intShapeId );
|
|
||||||
if ( s.ShapeType() != TopAbs_EDGE ) continue;
|
|
||||||
for ( exVe.Init( s, TopAbs_VERTEX ); exVe.More(); exVe.Next())
|
|
||||||
{
|
|
||||||
set<int> internalEdges;
|
|
||||||
for ( ancIt.Initialize( aMesh.GetAncestors( exVe.Current() ));
|
|
||||||
ancIt.More(); ancIt.Next() )
|
|
||||||
{
|
|
||||||
if ( ancIt.Value().ShapeType() != TopAbs_EDGE ) continue;
|
|
||||||
int edgeID = meshDS->ShapeToIndex( ancIt.Value() );
|
|
||||||
if ( internalShapeIds.count( edgeID ))
|
|
||||||
internalEdges.insert( edgeID );
|
|
||||||
}
|
|
||||||
if ( internalEdges.size() > 1 )
|
|
||||||
internalShapeIds.insert( meshDS->ShapeToIndex( exVe.Current() ));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// find border shapes and mesh elements
|
|
||||||
findBorders( internalShapeIds, helper, borderElems, borderFaceIds );
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
// Feed the Netgen with surface mesh
|
// Feed the Netgen with surface mesh
|
||||||
@ -408,12 +213,12 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh,
|
|||||||
if ( aMesh.NbQuadrangles() > 0 )
|
if ( aMesh.NbQuadrangles() > 0 )
|
||||||
Adaptor.Compute(aMesh,aShape);
|
Adaptor.Compute(aMesh,aShape);
|
||||||
|
|
||||||
for ( exFa.ReInit(); exFa.More(); exFa.Next())
|
for ( TopExp_Explorer exFa( aShape, TopAbs_FACE ); exFa.More(); exFa.Next())
|
||||||
{
|
{
|
||||||
const TopoDS_Shape& aShapeFace = exFa.Current();
|
const TopoDS_Shape& aShapeFace = exFa.Current();
|
||||||
int faceID = meshDS->ShapeToIndex( aShapeFace );
|
int faceID = meshDS->ShapeToIndex( aShapeFace );
|
||||||
bool isInternalFace = internalShapeIds.count( faceID );
|
bool isInternalFace = internals.isInternalShape( faceID );
|
||||||
bool isBorderFace = borderFaceIds.count( faceID );
|
bool isBorderFace = internals.isBorderFace( faceID );
|
||||||
bool isRev = false;
|
bool isRev = false;
|
||||||
if ( checkReverse && !isInternalFace &&
|
if ( checkReverse && !isInternalFace &&
|
||||||
helper.NbAncestors(aShapeFace, aMesh, aShape.ShapeType()) > 1 )
|
helper.NbAncestors(aShapeFace, aMesh, aShape.ShapeType()) > 1 )
|
||||||
@ -471,7 +276,7 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh,
|
|||||||
node = SMESH_Algo::VertexNode( TopoDS::Vertex( vertex ), meshDS );
|
node = SMESH_Algo::VertexNode( TopoDS::Vertex( vertex ), meshDS );
|
||||||
hasDegen = true;
|
hasDegen = true;
|
||||||
}
|
}
|
||||||
bool isDblN = isDblF && internalShapeIds.count( shapeID );
|
bool isDblN = isDblF && internals.isInternalShape( shapeID );
|
||||||
int& ngID = nodeToNetgenID[isDblN].insert(TN2ID( node, invalid_ID )).first->second;
|
int& ngID = nodeToNetgenID[isDblN].insert(TN2ID( node, invalid_ID )).first->second;
|
||||||
if ( ngID == invalid_ID )
|
if ( ngID == invalid_ID )
|
||||||
{
|
{
|
||||||
@ -681,7 +486,7 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh,
|
|||||||
int Netgen_triangle[3];
|
int Netgen_triangle[3];
|
||||||
int Netgen_tetrahedron[4];
|
int Netgen_tetrahedron[4];
|
||||||
|
|
||||||
TNetgenLibWrapper ngLib;
|
NETGENPlugin_NetgenLibWrapper ngLib;
|
||||||
Ng_Mesh * Netgen_mesh = ngLib._ngMesh;
|
Ng_Mesh * Netgen_mesh = ngLib._ngMesh;
|
||||||
|
|
||||||
// set nodes and remember thier netgen IDs
|
// set nodes and remember thier netgen IDs
|
||||||
|
Loading…
Reference in New Issue
Block a user