mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-04-24 10:02:04 +05:00
[bos #42217][EDF 28921] Horseshoe with bodyfitting.
Nodes linked to a null nodes without any possible splits now being cleared befor splits initialization. This prevents building non-planar faces in cases when the source geometry surface coincident with an intermediate grid plane.
This commit is contained in:
parent
05136f0f59
commit
312549ec64
@ -393,6 +393,28 @@ void Hexahedron::_Node::Add( const E_IntersectPoint* ip )
|
|||||||
_node = _intPoint->_node = node;
|
_node = _intPoint->_node = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Hexahedron::_Node::clear()
|
||||||
|
{
|
||||||
|
_node = nullptr;
|
||||||
|
_boundaryCornerNode = nullptr;
|
||||||
|
_intPoint = nullptr;
|
||||||
|
_usedInFace = nullptr;
|
||||||
|
_isInternalFlags = IS_NOT_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hexahedron::_Link::clear()
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < nodesNum; ++i)
|
||||||
|
{
|
||||||
|
if (_nodes[i])
|
||||||
|
_nodes[i]->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
_fIntPoints.clear();
|
||||||
|
_fIntNodes.clear();
|
||||||
|
_splits.clear();
|
||||||
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Return IDs of SOLIDs interfering with this Hexahedron
|
* \brief Return IDs of SOLIDs interfering with this Hexahedron
|
||||||
@ -606,6 +628,8 @@ void Hexahedron::init( size_t i, size_t j, size_t k, const Solid* solid )
|
|||||||
// this method can be called in parallel, so use own helper
|
// this method can be called in parallel, so use own helper
|
||||||
SMESH_MesherHelper helper( *_grid->_helper->GetMesh() );
|
SMESH_MesherHelper helper( *_grid->_helper->GetMesh() );
|
||||||
|
|
||||||
|
clearNodesLinkedToNull(solid, helper);
|
||||||
|
|
||||||
// Create sub-links (_Link::_splits) by splitting links with _Link::_fIntPoints
|
// Create sub-links (_Link::_splits) by splitting links with _Link::_fIntPoints
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
_Link split;
|
_Link split;
|
||||||
@ -798,6 +822,104 @@ void Hexahedron::init( size_t i, size_t j, size_t k, const Solid* solid )
|
|||||||
|
|
||||||
} // init( _i, _j, _k )
|
} // init( _i, _j, _k )
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Clear nodes linked to null by not splitted links.
|
||||||
|
* Exclude from computation all nodes those linked to null without any splits in links.
|
||||||
|
* This prevents building non-planar faces in cases when the source geometry surface
|
||||||
|
* coincident with an intermediate grid plane.
|
||||||
|
*/
|
||||||
|
void Hexahedron::clearNodesLinkedToNull(const Solid* solid, SMESH_MesherHelper& helper)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < HEX_LINKS_NUM; ++i)
|
||||||
|
{
|
||||||
|
_Link& link = _hexLinks[i];
|
||||||
|
|
||||||
|
if (isSplittedLink(solid, helper, link))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Links where both nodes are valid should have itself as a split.
|
||||||
|
// Check if we have at least one null node here for a chance if we have
|
||||||
|
// some unexpected edge case.
|
||||||
|
_Node* n1 = link._nodes[0];
|
||||||
|
_Node* n2 = link._nodes[1];
|
||||||
|
|
||||||
|
if (!n1->_node || !n2->_node)
|
||||||
|
{
|
||||||
|
link.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Returns true if the link will be splitted on the Hexaedron initialization
|
||||||
|
*/
|
||||||
|
bool Hexahedron::isSplittedLink(const Solid* solid, SMESH_MesherHelper& helper, const Hexahedron::_Link& linkIn) const
|
||||||
|
{
|
||||||
|
_Link split;
|
||||||
|
|
||||||
|
_Link link = linkIn;
|
||||||
|
link._fIntNodes.clear();
|
||||||
|
link._fIntNodes.reserve( link._fIntPoints.size() );
|
||||||
|
|
||||||
|
std::vector<_Node> intNodes;
|
||||||
|
intNodes.reserve(link._fIntPoints.size());
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < link._fIntPoints.size(); ++i )
|
||||||
|
if ( solid->ContainsAny( link._fIntPoints[i]->_faceIDs ))
|
||||||
|
{
|
||||||
|
intNodes.emplace_back(nullptr, link._fIntPoints[i]);
|
||||||
|
link._fIntNodes.push_back( & intNodes.back() );
|
||||||
|
}
|
||||||
|
|
||||||
|
link._splits.clear();
|
||||||
|
split._nodes[ 0 ] = link._nodes[0];
|
||||||
|
bool isOut = ( ! link._nodes[0]->Node() );
|
||||||
|
bool checkTransition = false;
|
||||||
|
for ( size_t i = 0; i < link._fIntNodes.size(); ++i )
|
||||||
|
{
|
||||||
|
const bool isGridNode = ( ! link._fIntNodes[i]->Node() );
|
||||||
|
if ( !isGridNode ) // intersection non-coincident with a grid node
|
||||||
|
{
|
||||||
|
if ( split._nodes[ 0 ]->Node() && !isOut )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
split._nodes[ 0 ] = link._fIntNodes[i];
|
||||||
|
checkTransition = true;
|
||||||
|
}
|
||||||
|
else // FACE intersection coincident with a grid node (at link ends)
|
||||||
|
{
|
||||||
|
checkTransition = ( i == 0 && link._nodes[0]->Node() );
|
||||||
|
}
|
||||||
|
if ( checkTransition )
|
||||||
|
{
|
||||||
|
const vector< TGeomID >& faceIDs = link._fIntNodes[i]->_intPoint->_faceIDs;
|
||||||
|
if ( _grid->IsInternal( faceIDs.back() ))
|
||||||
|
isOut = false;
|
||||||
|
else if ( faceIDs.size() > 1 || _eIntPoints.size() > 0 )
|
||||||
|
isOut = isOutPoint( link, i, helper, solid );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool okTransi = _grid->IsCorrectTransition( faceIDs[0], solid );
|
||||||
|
switch ( link._fIntNodes[i]->FaceIntPnt()->_transition ) {
|
||||||
|
case Trans_OUT: isOut = okTransi; break;
|
||||||
|
case Trans_IN : isOut = !okTransi; break;
|
||||||
|
default:
|
||||||
|
isOut = isOutPoint( link, i, helper, solid );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( link._nodes[ 1 ]->Node() && split._nodes[ 0 ]->Node() && !isOut )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Compute mesh volumes resulted from intersection of the Hexahedron
|
* \brief Compute mesh volumes resulted from intersection of the Hexahedron
|
||||||
|
@ -156,17 +156,22 @@ namespace Cartesian3D
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Add( const StdMeshers::Cartesian3D::E_IntersectPoint* ip );
|
void Add( const StdMeshers::Cartesian3D::E_IntersectPoint* ip );
|
||||||
|
void clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------
|
||||||
struct _Link // link connecting two _Node's
|
struct _Link // link connecting two _Node's
|
||||||
{
|
{
|
||||||
_Node* _nodes[2];
|
static const std::size_t nodesNum = 2;
|
||||||
_Face* _faces[2]; // polygons sharing a link
|
|
||||||
|
_Node* _nodes[nodesNum];
|
||||||
|
_Face* _faces[nodesNum]; // polygons sharing a link
|
||||||
std::vector< const StdMeshers::Cartesian3D::F_IntersectPoint* > _fIntPoints; // GridLine intersections with FACEs
|
std::vector< const StdMeshers::Cartesian3D::F_IntersectPoint* > _fIntPoints; // GridLine intersections with FACEs
|
||||||
std::vector< _Node* > _fIntNodes; // _Node's at _fIntPoints
|
std::vector< _Node* > _fIntNodes; // _Node's at _fIntPoints
|
||||||
std::vector< _Link > _splits;
|
std::vector< _Link > _splits;
|
||||||
_Link(): _nodes{ 0, 0 }, _faces{ 0, 0 } {}
|
_Link(): _nodes{ 0, 0 }, _faces{ 0, 0 } {}
|
||||||
|
|
||||||
|
void clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------
|
||||||
@ -388,9 +393,12 @@ namespace Cartesian3D
|
|||||||
};
|
};
|
||||||
|
|
||||||
// topology of a hexahedron
|
// topology of a hexahedron
|
||||||
_Node _hexNodes [8];
|
static const std::size_t HEX_NODES_NUM = 8;
|
||||||
_Link _hexLinks [12];
|
static const std::size_t HEX_LINKS_NUM = 12;
|
||||||
_Face _hexQuads [6];
|
static const std::size_t HEX_QUADS_NUM = 6;
|
||||||
|
_Node _hexNodes [HEX_NODES_NUM];
|
||||||
|
_Link _hexLinks [HEX_LINKS_NUM];
|
||||||
|
_Face _hexQuads [HEX_QUADS_NUM];
|
||||||
|
|
||||||
// faces resulted from hexahedron intersection
|
// faces resulted from hexahedron intersection
|
||||||
std::vector< _Face > _polygons;
|
std::vector< _Face > _polygons;
|
||||||
@ -426,6 +434,8 @@ namespace Cartesian3D
|
|||||||
Hexahedron(const Hexahedron& other, size_t i, size_t j, size_t k, int cellID );
|
Hexahedron(const Hexahedron& other, size_t i, size_t j, size_t k, int cellID );
|
||||||
void init( size_t i, size_t j, size_t k, const Solid* solid=0 );
|
void init( size_t i, size_t j, size_t k, const Solid* solid=0 );
|
||||||
void init( size_t i );
|
void init( size_t i );
|
||||||
|
void clearNodesLinkedToNull(const Solid* solid, SMESH_MesherHelper& helper);
|
||||||
|
bool isSplittedLink(const Solid* solid, SMESH_MesherHelper& helper, const Hexahedron::_Link& linkIn) const;
|
||||||
void setIJK( size_t i );
|
void setIJK( size_t i );
|
||||||
/*Auxiliary methods to extract operations from monolitic compute method*/
|
/*Auxiliary methods to extract operations from monolitic compute method*/
|
||||||
void defineHexahedralFaces( const Solid* solid, const IsInternalFlag intFlag );
|
void defineHexahedralFaces( const Solid* solid, const IsInternalFlag intFlag );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user