mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-04-15 18:11:21 +05:00
0021468: EDF 2073 SMESH: Body-fitting algo creates elements in hole
This commit is contained in:
parent
2633709b28
commit
5c991bb2b7
@ -173,9 +173,9 @@ namespace
|
|||||||
_name1 = nv1; _name2 = nv2; _nameConst = nConst;
|
_name1 = nv1; _name2 = nv2; _nameConst = nConst;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t I() { return _curInd[0]; }
|
size_t I() const { return _curInd[0]; }
|
||||||
size_t J() { return _curInd[1]; }
|
size_t J() const { return _curInd[1]; }
|
||||||
size_t K() { return _curInd[2]; }
|
size_t K() const { return _curInd[2]; }
|
||||||
void SetIJK( size_t i, size_t j, size_t k )
|
void SetIJK( size_t i, size_t j, size_t k )
|
||||||
{
|
{
|
||||||
_curInd[0] = i; _curInd[1] = j; _curInd[2] = k;
|
_curInd[0] = i; _curInd[1] = j; _curInd[2] = k;
|
||||||
@ -204,6 +204,7 @@ namespace
|
|||||||
double _tol, _minCellSize;
|
double _tol, _minCellSize;
|
||||||
|
|
||||||
vector< const SMDS_MeshNode* > _nodes; // mesh nodes at grid nodes
|
vector< const SMDS_MeshNode* > _nodes; // mesh nodes at grid nodes
|
||||||
|
vector< bool > _isBndNode; // is mesh node at intersection with geometry
|
||||||
|
|
||||||
size_t NodeIndex( size_t i, size_t j, size_t k ) const
|
size_t NodeIndex( size_t i, size_t j, size_t k ) const
|
||||||
{
|
{
|
||||||
@ -321,6 +322,7 @@ namespace
|
|||||||
vector< _Node> _intNodes; // _Node's at GridLine intersections
|
vector< _Node> _intNodes; // _Node's at GridLine intersections
|
||||||
vector< _Link > _splits;
|
vector< _Link > _splits;
|
||||||
vector< _Face*> _faces;
|
vector< _Face*> _faces;
|
||||||
|
const GridLine* _line;
|
||||||
};
|
};
|
||||||
// --------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------
|
||||||
struct _OrientedLink
|
struct _OrientedLink
|
||||||
@ -336,11 +338,6 @@ namespace
|
|||||||
}
|
}
|
||||||
_Node* FirstNode() const { return _link->_nodes[ _reverse ]; }
|
_Node* FirstNode() const { return _link->_nodes[ _reverse ]; }
|
||||||
_Node* LastNode() const { return _link->_nodes[ !_reverse ]; }
|
_Node* LastNode() const { return _link->_nodes[ !_reverse ]; }
|
||||||
// int NbNodes() const { return 2 + _link->_intNodes.size(); }
|
|
||||||
// _Node* GetNode(const int i)
|
|
||||||
// {
|
|
||||||
// return ( 0 < i && i < NbNodes()-1 ) ? _link->_intNodes[i-1] : ( _link->_nodes[bool(i)]);
|
|
||||||
// }
|
|
||||||
};
|
};
|
||||||
// --------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------
|
||||||
struct _Face
|
struct _Face
|
||||||
@ -361,13 +358,14 @@ namespace
|
|||||||
|
|
||||||
double _sizeThreshold, _sideLength[3];
|
double _sizeThreshold, _sideLength[3];
|
||||||
|
|
||||||
int _nbCornerNodes, _nbIntNodes;
|
int _nbCornerNodes, _nbIntNodes, _nbBndNodes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Hexahedron(const double sizeThreshold, Grid* grid);
|
Hexahedron(const double sizeThreshold, Grid* grid);
|
||||||
void Init( size_t i, size_t j, size_t k );
|
void Init( size_t i, size_t j, size_t k );
|
||||||
int MakeElements(SMESH_MesherHelper& helper);
|
int MakeElements(SMESH_MesherHelper& helper);
|
||||||
private:
|
private:
|
||||||
|
bool isInHole() const;
|
||||||
bool checkPolyhedronSize() const;
|
bool checkPolyhedronSize() const;
|
||||||
bool addHexa (SMESH_MesherHelper& helper);
|
bool addHexa (SMESH_MesherHelper& helper);
|
||||||
bool addTetra(SMESH_MesherHelper& helper);
|
bool addTetra(SMESH_MesherHelper& helper);
|
||||||
@ -528,8 +526,10 @@ namespace
|
|||||||
void Grid::ComputeNodes(SMESH_MesherHelper& helper)
|
void Grid::ComputeNodes(SMESH_MesherHelper& helper)
|
||||||
{
|
{
|
||||||
// state of each node of the grid relative to the geomerty
|
// state of each node of the grid relative to the geomerty
|
||||||
vector< bool > isNodeOut( _coords[0].size() * _coords[1].size() * _coords[2].size(), false );
|
const size_t nbGridNodes = _coords[0].size() * _coords[1].size() * _coords[2].size();
|
||||||
_nodes.resize( isNodeOut.size(), 0 );
|
vector< bool > isNodeOut( nbGridNodes, false );
|
||||||
|
_nodes.resize( nbGridNodes, 0 );
|
||||||
|
_isBndNode.resize( nbGridNodes, false );
|
||||||
|
|
||||||
for ( int iDir = 0; iDir < 3; ++iDir ) // loop on 3 line directions
|
for ( int iDir = 0; iDir < 3; ++iDir ) // loop on 3 line directions
|
||||||
{
|
{
|
||||||
@ -590,7 +590,9 @@ namespace
|
|||||||
li.SetIndexOnLine( nodeCoord-coord0 );
|
li.SetIndexOnLine( nodeCoord-coord0 );
|
||||||
double xyz[3] = { _coords[0][ li.I() ], _coords[1][ li.J() ], _coords[2][ li.K() ]};
|
double xyz[3] = { _coords[0][ li.I() ], _coords[1][ li.J() ], _coords[2][ li.K() ]};
|
||||||
_nodes[ nodeIndex ] = helper.AddNode( xyz[0], xyz[1], xyz[2] );
|
_nodes[ nodeIndex ] = helper.AddNode( xyz[0], xyz[1], xyz[2] );
|
||||||
|
_isBndNode[ nodeIndex ] = true;
|
||||||
}
|
}
|
||||||
|
ip->_node = _nodes[ nodeIndex ];
|
||||||
if ( ++nodeCoord < coordEnd )
|
if ( ++nodeCoord < coordEnd )
|
||||||
nodeParam = *nodeCoord - *coord0;
|
nodeParam = *nodeCoord - *coord0;
|
||||||
}
|
}
|
||||||
@ -1059,12 +1061,14 @@ namespace
|
|||||||
void Hexahedron::Init( size_t i, size_t j, size_t k )
|
void Hexahedron::Init( size_t i, size_t j, size_t k )
|
||||||
{
|
{
|
||||||
// set nodes of grid to nodes of the hexahedron and
|
// set nodes of grid to nodes of the hexahedron and
|
||||||
// count nodes at hexahedron corners located IN geometry
|
// count nodes at hexahedron corners located IN and ON geometry
|
||||||
_nbCornerNodes = _nbIntNodes = 0;
|
_nbCornerNodes = _nbIntNodes = _nbBndNodes = 0;
|
||||||
size_t i000 = _grid->NodeIndex( i,j,k );
|
size_t i000 = _grid->NodeIndex( i,j,k );
|
||||||
for ( int iN = 0; iN < 8; ++iN )
|
for ( int iN = 0; iN < 8; ++iN )
|
||||||
|
{
|
||||||
_nbCornerNodes += bool(( _hexNodes[iN]._node = _grid->_nodes[ i000 + _nodeShift[iN] ]));
|
_nbCornerNodes += bool(( _hexNodes[iN]._node = _grid->_nodes[ i000 + _nodeShift[iN] ]));
|
||||||
|
_nbBndNodes += _grid->_isBndNode[ i000 + _nodeShift[iN] ];
|
||||||
|
}
|
||||||
// set intersection nodes from GridLine's to hexahedron links
|
// set intersection nodes from GridLine's to hexahedron links
|
||||||
int linkID = 0;
|
int linkID = 0;
|
||||||
_Link split;
|
_Link split;
|
||||||
@ -1087,6 +1091,7 @@ namespace
|
|||||||
{
|
{
|
||||||
GridLine& line = _grid->_lines[ iDir ][ lineIndex[ iL ]];
|
GridLine& line = _grid->_lines[ iDir ][ lineIndex[ iL ]];
|
||||||
_Link& link = _hexLinks[ linkID++ ];
|
_Link& link = _hexLinks[ linkID++ ];
|
||||||
|
link._line = &line;
|
||||||
link._intNodes.clear();
|
link._intNodes.clear();
|
||||||
link._splits.clear();
|
link._splits.clear();
|
||||||
split._nodes[ 0 ] = link._nodes[0];
|
split._nodes[ 0 ] = link._nodes[0];
|
||||||
@ -1123,7 +1128,7 @@ namespace
|
|||||||
int Hexahedron::MakeElements(SMESH_MesherHelper& helper)
|
int Hexahedron::MakeElements(SMESH_MesherHelper& helper)
|
||||||
{
|
{
|
||||||
int nbAddedVols = 0;
|
int nbAddedVols = 0;
|
||||||
if ( _nbCornerNodes == 8 && _nbIntNodes == 0 )
|
if ( _nbCornerNodes == 8 && _nbIntNodes == 0 && _nbBndNodes < _nbCornerNodes )
|
||||||
{
|
{
|
||||||
// order of _hexNodes is defined by enum SMESH_Block::TShapeID
|
// order of _hexNodes is defined by enum SMESH_Block::TShapeID
|
||||||
helper.AddVolume( _hexNodes[0].Node(), _hexNodes[2].Node(),
|
helper.AddVolume( _hexNodes[0].Node(), _hexNodes[2].Node(),
|
||||||
@ -1135,6 +1140,9 @@ namespace
|
|||||||
if ( _nbCornerNodes + _nbIntNodes < 4 )
|
if ( _nbCornerNodes + _nbIntNodes < 4 )
|
||||||
return nbAddedVols;
|
return nbAddedVols;
|
||||||
|
|
||||||
|
if ( _nbBndNodes == _nbCornerNodes && isInHole() )
|
||||||
|
return nbAddedVols;
|
||||||
|
|
||||||
_polygons.clear();
|
_polygons.clear();
|
||||||
|
|
||||||
vector<const SMDS_MeshNode* > polyhedraNodes;
|
vector<const SMDS_MeshNode* > polyhedraNodes;
|
||||||
@ -1148,7 +1156,7 @@ namespace
|
|||||||
_Link polyLink;
|
_Link polyLink;
|
||||||
polyLink._faces.reserve( 1 );
|
polyLink._faces.reserve( 1 );
|
||||||
|
|
||||||
for ( int iF = 0; iF < 6; ++iF )
|
for ( int iF = 0; iF < 6; ++iF ) // loop on 6 sides on a hexahedron
|
||||||
{
|
{
|
||||||
const _Face& quad = _hexQuads[ iF ] ;
|
const _Face& quad = _hexQuads[ iF ] ;
|
||||||
|
|
||||||
@ -1160,7 +1168,7 @@ namespace
|
|||||||
// add splits of a link to a polygon and collect info on nodes
|
// add splits of a link to a polygon and collect info on nodes
|
||||||
//int nbIn = 0, nbOut = 0, nbCorners = 0;
|
//int nbIn = 0, nbOut = 0, nbCorners = 0;
|
||||||
nodes.clear();
|
nodes.clear();
|
||||||
for ( int iE = 0; iE < 4; ++iE )
|
for ( int iE = 0; iE < 4; ++iE ) // loop on 4 sides of a quadrangle
|
||||||
{
|
{
|
||||||
int nbSpits = quad._links[ iE ].NbResultLinks();
|
int nbSpits = quad._links[ iE ].NbResultLinks();
|
||||||
for ( int iS = 0; iS < nbSpits; ++iS )
|
for ( int iS = 0; iS < nbSpits; ++iS )
|
||||||
@ -1306,6 +1314,48 @@ namespace
|
|||||||
return nbAddedVols;
|
return nbAddedVols;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Return true if the element is in a hole
|
||||||
|
*/
|
||||||
|
bool Hexahedron::isInHole() const
|
||||||
|
{
|
||||||
|
const int ijk[3] = { _lineInd[0].I(), _lineInd[0].J(), _lineInd[0].K() };
|
||||||
|
IntersectionPoint curIntPnt;
|
||||||
|
|
||||||
|
for ( int iDir = 0; iDir < 3; ++iDir )
|
||||||
|
{
|
||||||
|
const vector<double>& coords = _grid->_coords[ iDir ];
|
||||||
|
bool allLinksOut = true;
|
||||||
|
int linkID = iDir * 4;
|
||||||
|
for ( int i = 0; i < 4 && allLinksOut; ++i )
|
||||||
|
{
|
||||||
|
const _Link& link = _hexLinks[ linkID++ ];
|
||||||
|
if ( link._splits.empty() ) continue;
|
||||||
|
// check transition of the first node of a link
|
||||||
|
const IntersectionPoint* firstIntPnt = 0;
|
||||||
|
if ( link._nodes[0]->Node() ) // 1st node is a hexa corner
|
||||||
|
{
|
||||||
|
curIntPnt._paramOnLine = coords[ ijk[ iDir ]] - coords[0];
|
||||||
|
multiset< IntersectionPoint >::const_iterator ip =
|
||||||
|
link._line->_intPoints.upper_bound( curIntPnt );
|
||||||
|
--ip;
|
||||||
|
firstIntPnt = &(*ip);
|
||||||
|
}
|
||||||
|
else if ( !link._intNodes.empty() )
|
||||||
|
{
|
||||||
|
firstIntPnt = link._intNodes[0]._intPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( firstIntPnt && firstIntPnt->_transition == Trans_IN )
|
||||||
|
allLinksOut = false;
|
||||||
|
}
|
||||||
|
if ( allLinksOut )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Return true if a polyhedron passes _sizeThreshold criterion
|
* \brief Return true if a polyhedron passes _sizeThreshold criterion
|
||||||
|
Loading…
x
Reference in New Issue
Block a user