mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-18 10:40:36 +05:00
0021543: EDF 1978 SMESH: Viscous layer for 2D meshes
debug on a complex sketch + bool improve();
This commit is contained in:
parent
2f485c1e90
commit
d05c72902a
@ -336,6 +336,7 @@ namespace VISCOUS_2D
|
||||
bool fixCollisions();
|
||||
bool refine();
|
||||
bool shrink();
|
||||
bool improve();
|
||||
bool toShrinkForAdjacent( const TopoDS_Face& adjFace,
|
||||
const TopoDS_Edge& E,
|
||||
const TopoDS_Vertex& V);
|
||||
@ -429,9 +430,9 @@ StdMeshers_ViscousLayers2D::Compute(SMESH_Mesh& theMesh,
|
||||
SMESH_ComputeErrorPtr error = builder.GetError();
|
||||
if ( error && !error->IsOK() )
|
||||
theMesh.GetSubMesh( theFace )->GetComputeError() = error;
|
||||
else if ( !pm )
|
||||
pm.reset( new SMESH_ProxyMesh( theMesh ));
|
||||
//pm.reset();
|
||||
// else if ( !pm )
|
||||
// pm.reset( new SMESH_ProxyMesh( theMesh ));
|
||||
pm.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -527,8 +528,6 @@ SMESH_ProxyMesh::Ptr _ViscousBuilder2D::Compute()
|
||||
if ( !_error->IsOK() )
|
||||
return _proxyMesh;
|
||||
|
||||
//PyDump debugDump;
|
||||
|
||||
if ( !findEdgesWithLayers() ) // analysis of a shape
|
||||
return _proxyMesh;
|
||||
|
||||
@ -544,11 +543,7 @@ SMESH_ProxyMesh::Ptr _ViscousBuilder2D::Compute()
|
||||
if ( ! refine() ) // make faces
|
||||
return _proxyMesh;
|
||||
|
||||
// for ( size_t i = 0; i < _facesToRecompute.size(); ++i )
|
||||
// _mesh->GetSubMesh( _facesToRecompute[i] )->ComputeStateEngine( SMESH_subMesh::COMPUTE );
|
||||
|
||||
//makeGroupOfLE(); // debug
|
||||
//debugDump.Finish();
|
||||
improve();
|
||||
|
||||
return _proxyMesh;
|
||||
}
|
||||
@ -1117,7 +1112,7 @@ bool _ViscousBuilder2D::fixCollisions()
|
||||
for ( size_t iLE = L1.FirstLEdge(); iLE < L1._lEdges.size(); ++iLE )
|
||||
{
|
||||
_LayerEdge& LE1 = L1._lEdges[iLE];
|
||||
//if ( LE1._isBlocked ) continue;
|
||||
if ( LE1._isBlocked ) continue;
|
||||
foundSegs.clear();
|
||||
L2._segTree->GetSegmentsNear( LE1._ray, foundSegs );
|
||||
for ( size_t i = 0; i < foundSegs.size(); ++i )
|
||||
@ -1355,7 +1350,8 @@ bool _ViscousBuilder2D::shrink()
|
||||
!curveInt.IsEmpty() &&
|
||||
curveInt.Point( 1 ).Value().Distance( uvFSeg2Out ) <= maxDist2d )
|
||||
{ /* convex VERTEX */
|
||||
u = curveInt.Point( 1 ).ParamOnFirst(); /* |L seg2
|
||||
length2D = Abs( u - curveInt.Point( 1 ).ParamOnFirst() );
|
||||
/* |L seg2
|
||||
* | o---o---
|
||||
* | / |
|
||||
* |/ | L2
|
||||
@ -1376,14 +1372,14 @@ bool _ViscousBuilder2D::shrink()
|
||||
if ( length2D == 0 )
|
||||
length2D = ( isR ? L._leftLine->_lEdges.back() : L._rightLine->_lEdges.front() )._length2D;
|
||||
}
|
||||
if ( length2D > 0 ) {
|
||||
// move u to the internal boundary of layers
|
||||
double maxLen3D = Min( _thickness, edgeLen / ( 1 + nbAdvancable ));
|
||||
double maxLen2D = maxLen3D * nearLE._len2dTo3dRatio;
|
||||
if ( length2D > maxLen2D )
|
||||
length2D = maxLen2D;
|
||||
u += length2D * sign;
|
||||
}
|
||||
// move u to the internal boundary of layers
|
||||
double maxLen3D = Min( _thickness, edgeLen / ( 1 + nbAdvancable ));
|
||||
double maxLen2D = maxLen3D * nearLE._len2dTo3dRatio;
|
||||
if ( length2D > maxLen2D )
|
||||
length2D = maxLen2D;
|
||||
nearLE._uvIn = nearLE._uvOut + nearLE._normal2D * length2D;
|
||||
|
||||
u += length2D * sign;
|
||||
nodeDataVec[ iPEnd ].param = u;
|
||||
|
||||
gp_Pnt2d newUV = pcurve->Value( u );
|
||||
@ -1578,7 +1574,7 @@ bool _ViscousBuilder2D::refine()
|
||||
|
||||
//if ( L._leftLine->_advancable ) L._lEdges[0] = L._leftLine->_lEdges.back();
|
||||
|
||||
// replace an inactive _LayerEdge with an active one of a neighbour _PolyLine
|
||||
// replace an inactive (1st) _LayerEdge with an active one of a neighbour _PolyLine
|
||||
size_t iLE = 0, nbLE = L._lEdges.size();
|
||||
if ( /*!L._leftLine->_advancable &&*/ L.IsCommonEdgeShared( *L._leftLine ))
|
||||
{
|
||||
@ -1597,9 +1593,7 @@ bool _ViscousBuilder2D::refine()
|
||||
{
|
||||
int nbRemove = 0, deltaIt = isR ? -1 : +1;
|
||||
_PolyLine::TEdgeIterator eIt = isR ? L._lEdges.end()-1 : L._lEdges.begin();
|
||||
// HEURISTICS !!! elongate the first _LayerEdge
|
||||
gp_XY newIn = eIt->_uvOut + eIt->_normal2D * eIt->_length2D/* * 2*/;
|
||||
_Segment seg1( eIt->_uvOut, newIn );
|
||||
_Segment seg1( eIt->_uvOut, eIt->_uvIn );
|
||||
for ( eIt += deltaIt; nbRemove < L._lEdges.size()-2; eIt += deltaIt )
|
||||
{
|
||||
_Segment seg2( eIt->_uvOut, eIt->_uvIn );
|
||||
@ -1617,6 +1611,36 @@ bool _ViscousBuilder2D::refine()
|
||||
}
|
||||
}
|
||||
|
||||
// limit length of neighbour _LayerEdge's to avoid sharp change of layers thickness
|
||||
vector< double > segLen( L._lEdges.size() );
|
||||
segLen[0] = 0.0;
|
||||
for ( size_t i = 1; i < segLen.size(); ++i )
|
||||
{
|
||||
// accumulate length of segments
|
||||
double sLen = (L._lEdges[i-1]._uvOut - L._lEdges[i]._uvOut ).Modulus();
|
||||
segLen[i] = segLen[i-1] + sLen;
|
||||
}
|
||||
for ( int isR = 0; isR < 2; ++isR )
|
||||
{
|
||||
size_t iF = 0, iL = L._lEdges.size()-1;
|
||||
size_t *i = isR ? &iL : &iF;
|
||||
//size_t iRef = *i;
|
||||
gp_XY uvInPrev = L._lEdges[ *i ]._uvIn;
|
||||
double weight = 0;
|
||||
for ( ++iF, --iL; iF < L._lEdges.size()-1; ++iF, --iL )
|
||||
{
|
||||
_LayerEdge& LE = L._lEdges[*i];
|
||||
gp_XY tangent ( LE._normal2D.Y(), -LE._normal2D.X() );
|
||||
weight += Abs( tangent * ( uvInPrev - LE._uvIn )) / segLen.back();
|
||||
double proj = LE._normal2D * ( uvInPrev - LE._uvOut );
|
||||
if ( LE._length2D < proj )
|
||||
weight += 0.75 * ( 1 - weight ); // length decrease is more preferable
|
||||
LE._length2D = weight * LE._length2D + ( 1 - weight ) * proj;
|
||||
LE._uvIn = LE._uvOut + LE._normal2D * LE._length2D;
|
||||
uvInPrev = LE._uvIn;
|
||||
}
|
||||
}
|
||||
|
||||
// calculate intermediate UV on _LayerEdge's ( _LayerEdge::_uvRefined )
|
||||
for ( ; iLE < nbLE; ++iLE )
|
||||
{
|
||||
@ -1655,8 +1679,6 @@ bool _ViscousBuilder2D::refine()
|
||||
size_t iS, iN0 = hasLeftNode, nbN = innerNodes.size() - hasRightNode;
|
||||
L._leftNodes .resize( _hyp->GetNumberLayers() );
|
||||
L._rightNodes.resize( _hyp->GetNumberLayers() );
|
||||
vector< double > segLen( L._lEdges.size() );
|
||||
segLen[0] = 0.0;
|
||||
for ( int iF = 0; iF < _hyp->GetNumberLayers(); ++iF ) // loop on layers of faces
|
||||
{
|
||||
// get accumulated length of intermediate segments
|
||||
@ -1720,6 +1742,59 @@ bool _ViscousBuilder2D::refine()
|
||||
return true;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Improve quality of the created mesh elements
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
bool _ViscousBuilder2D::improve()
|
||||
{
|
||||
if ( !_proxyMesh )
|
||||
return false;
|
||||
|
||||
// faces to smooth
|
||||
TIDSortedElemSet facesToSmooth;
|
||||
if ( SMESHDS_SubMesh* sm = getMeshDS()->MeshElements( _face ))
|
||||
{
|
||||
SMDS_ElemIteratorPtr fIt = sm->GetElements();
|
||||
while ( fIt->more() )
|
||||
facesToSmooth.insert( facesToSmooth.end(), fIt->next() );
|
||||
}
|
||||
|
||||
// fixed nodes on EDGE's
|
||||
std::set<const SMDS_MeshNode*> fixedNodes;
|
||||
for ( size_t iWire = 0; iWire < _faceSideVec.size(); ++iWire )
|
||||
{
|
||||
StdMeshers_FaceSidePtr wire = _faceSideVec[ iWire ];
|
||||
const vector<UVPtStruct>& points = wire->GetUVPtStruct();
|
||||
for ( size_t i = 0; i < points.size(); ++i )
|
||||
fixedNodes.insert( fixedNodes.end(), points[i].node );
|
||||
}
|
||||
// fixed proxy nodes
|
||||
for ( size_t iL = 0; iL < _polyLineVec.size(); ++iL )
|
||||
{
|
||||
_PolyLine& L = _polyLineVec[ iL ];
|
||||
const TopoDS_Edge& E = L._wire->Edge( L._edgeInd );
|
||||
if ( const SMESH_ProxyMesh::SubMesh* sm = _proxyMesh->GetProxySubMesh( E ))
|
||||
{
|
||||
const UVPtStructVec& points = sm->GetUVPtStructVec();
|
||||
for ( size_t i = 0; i < points.size(); ++i )
|
||||
fixedNodes.insert( fixedNodes.end(), points[i].node );
|
||||
}
|
||||
for ( size_t i = 0; i < L._rightNodes.size(); ++i )
|
||||
fixedNodes.insert( fixedNodes.end(), L._rightNodes[i] );
|
||||
}
|
||||
|
||||
// smoothing
|
||||
SMESH_MeshEditor editor( _mesh );
|
||||
editor.Smooth( facesToSmooth, fixedNodes, SMESH_MeshEditor::CENTROIDAL, /*nbIt = */3 );
|
||||
//editor.Smooth( facesToSmooth, fixedNodes, SMESH_MeshEditor::LAPLACIAN, /*nbIt = */1 );
|
||||
//editor.Smooth( facesToSmooth, fixedNodes, SMESH_MeshEditor::CENTROIDAL, /*nbIt = */1 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Remove elements and nodes from a face
|
||||
|
Loading…
Reference in New Issue
Block a user