mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-19 00:30:36 +05:00
IPAL22856 2D quadrangle mesher of reduced type works wrong
change algorithm as requested by IPAL22856 - care of symmetry
This commit is contained in:
parent
ff4dc09d85
commit
aad57bda9f
@ -2793,7 +2793,168 @@ bool StdMeshers_Quadrangle_2D::ComputeReduced (SMESH_Mesh & aMesh,
|
|||||||
int curr_base_len = nb;
|
int curr_base_len = nb;
|
||||||
int next_base_len = 0;
|
int next_base_len = 0;
|
||||||
|
|
||||||
if ( is_tree_42 || is_tree_31 )
|
if ( true )
|
||||||
|
{ // ------------------------------------------------------------------
|
||||||
|
// New algorithm implemented by request of IPAL22856
|
||||||
|
// "2D quadrangle mesher of reduced type works wrong"
|
||||||
|
// http://bugtracker.opencascade.com/show_bug.cgi?id=22856
|
||||||
|
|
||||||
|
// the algorithm is following: all reduces are centred in horizontal
|
||||||
|
// direction and are distributed among all rows
|
||||||
|
|
||||||
|
if (ncol_bot > max_tree42) {
|
||||||
|
is_lin_31 = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ((ncol_top/3)*3 == ncol_top ) {
|
||||||
|
is_lin_31 = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
is_lin_42 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const int col_top_size = is_lin_42 ? 2 : 1;
|
||||||
|
const int col_base_size = is_lin_42 ? 4 : 3;
|
||||||
|
|
||||||
|
// Compute nb of "columns" (like in "linear" simple reducing) in all rows
|
||||||
|
|
||||||
|
vector<int> nb_col_by_row;
|
||||||
|
|
||||||
|
int delta_all = nb - nt;
|
||||||
|
int delta_one_col = nrows * 2;
|
||||||
|
int nb_col = delta_all / delta_one_col;
|
||||||
|
int remainder = delta_all - nb_col * delta_one_col;
|
||||||
|
if (remainder > 0) {
|
||||||
|
nb_col++;
|
||||||
|
}
|
||||||
|
if ( nb_col * col_top_size >= nt ) // == "tree" reducing situation
|
||||||
|
{
|
||||||
|
// top row is full (all elements reduced), add "columns" one by one
|
||||||
|
// in rows below until all bottom elements are reduced
|
||||||
|
nb_col = ( nt - 1 ) / col_top_size;
|
||||||
|
nb_col_by_row.resize( nrows, nb_col );
|
||||||
|
int nbrows_not_full = nrows - 1;
|
||||||
|
int cur_top_size = nt - 1;
|
||||||
|
remainder = delta_all - nb_col * delta_one_col;
|
||||||
|
while ( remainder > 0 )
|
||||||
|
{
|
||||||
|
delta_one_col = nbrows_not_full * 2;
|
||||||
|
int nb_col_add = remainder / delta_one_col;
|
||||||
|
cur_top_size += 2 * nb_col_by_row[ nbrows_not_full ];
|
||||||
|
int nb_col_free = cur_top_size / col_top_size - nb_col_by_row[ nbrows_not_full-1 ];
|
||||||
|
if ( nb_col_add > nb_col_free )
|
||||||
|
nb_col_add = nb_col_free;
|
||||||
|
for ( int irow = 0; irow < nbrows_not_full; ++irow )
|
||||||
|
nb_col_by_row[ irow ] += nb_col_add;
|
||||||
|
nbrows_not_full --;
|
||||||
|
remainder -= nb_col_add * delta_one_col;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // == "linear" reducing situation
|
||||||
|
{
|
||||||
|
nb_col_by_row.resize( nrows, nb_col );
|
||||||
|
if (remainder > 0)
|
||||||
|
for ( int irow = remainder / 2; irow < nrows; ++irow )
|
||||||
|
nb_col_by_row[ irow ]--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make elements
|
||||||
|
|
||||||
|
PReduceFunction reduceFunction = & ( is_lin_42 ? reduce42 : reduce31 );
|
||||||
|
|
||||||
|
const int reduce_grp_size = is_lin_42 ? 4 : 3;
|
||||||
|
|
||||||
|
for (i = 1; i < nr; i++) // layer by layer
|
||||||
|
{
|
||||||
|
nb_col = nb_col_by_row[ i-1 ];
|
||||||
|
int nb_next = curr_base_len - nb_col * 2;
|
||||||
|
if (nb_next < nt) nb_next = nt;
|
||||||
|
|
||||||
|
const double y = uv_el[ i ].normParam;
|
||||||
|
|
||||||
|
if ( i + 1 == nr ) // top
|
||||||
|
{
|
||||||
|
next_base = uv_et;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
next_base.clear();
|
||||||
|
next_base.resize( nb_next, nullUVPtStruct );
|
||||||
|
next_base.front() = uv_el[i];
|
||||||
|
next_base.back() = uv_er[i];
|
||||||
|
|
||||||
|
// compute normalized param u
|
||||||
|
double du = 1. / ( nb_next - 1 );
|
||||||
|
next_base[0].normParam = 0.;
|
||||||
|
for ( j = 1; j < nb_next; ++j )
|
||||||
|
next_base[j].normParam = next_base[j-1].normParam + du;
|
||||||
|
}
|
||||||
|
uv[ UV_L ].SetCoord( next_base.front().u, next_base.front().v );
|
||||||
|
uv[ UV_R ].SetCoord( next_base.back().u, next_base.back().v );
|
||||||
|
|
||||||
|
int free_left = ( curr_base_len - 1 - nb_col * col_base_size ) / 2;
|
||||||
|
int free_middle = curr_base_len - 1 - nb_col * col_base_size - 2 * free_left;
|
||||||
|
|
||||||
|
// not reduced left elements
|
||||||
|
for (j = 0; j < free_left; j++)
|
||||||
|
{
|
||||||
|
// f (i + 1, j + 1)
|
||||||
|
const SMDS_MeshNode*& Nf = next_base[++next_base_len].node;
|
||||||
|
if ( !Nf )
|
||||||
|
Nf = makeNode( next_base[ next_base_len ], y, quad, uv, myHelper, S );
|
||||||
|
|
||||||
|
myHelper->AddFace(curr_base[ j ].node,
|
||||||
|
curr_base[ j+1 ].node,
|
||||||
|
Nf,
|
||||||
|
next_base[ next_base_len-1 ].node);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int icol = 1; icol <= nb_col; icol++)
|
||||||
|
{
|
||||||
|
// add "H"
|
||||||
|
reduceFunction( curr_base, next_base, j, next_base_len, quad, uv, y, myHelper, S );
|
||||||
|
|
||||||
|
j += reduce_grp_size;
|
||||||
|
|
||||||
|
// elements in the middle of "columns" added for symmetry
|
||||||
|
if ( free_middle > 0 && ( nb_col % 2 == 0 ) && icol == nb_col / 2 )
|
||||||
|
{
|
||||||
|
for (int imiddle = 1; imiddle <= free_middle; imiddle++) {
|
||||||
|
// f (i + 1, j + imiddle)
|
||||||
|
const SMDS_MeshNode*& Nf = next_base[++next_base_len].node;
|
||||||
|
if ( !Nf )
|
||||||
|
Nf = makeNode( next_base[ next_base_len ], y, quad, uv, myHelper, S );
|
||||||
|
|
||||||
|
myHelper->AddFace(curr_base[ j-1+imiddle ].node,
|
||||||
|
curr_base[ j +imiddle ].node,
|
||||||
|
Nf,
|
||||||
|
next_base[ next_base_len-1 ].node);
|
||||||
|
}
|
||||||
|
j += free_middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// not reduced right elements
|
||||||
|
for (; j < curr_base_len-1; j++) {
|
||||||
|
// f (i + 1, j + 1)
|
||||||
|
const SMDS_MeshNode*& Nf = next_base[++next_base_len].node;
|
||||||
|
if ( !Nf )
|
||||||
|
Nf = makeNode( next_base[ next_base_len ], y, quad, uv, myHelper, S );
|
||||||
|
|
||||||
|
myHelper->AddFace(curr_base[ j ].node,
|
||||||
|
curr_base[ j+1 ].node,
|
||||||
|
Nf,
|
||||||
|
next_base[ next_base_len-1 ].node);
|
||||||
|
}
|
||||||
|
|
||||||
|
curr_base_len = next_base_len + 1;
|
||||||
|
next_base_len = 0;
|
||||||
|
curr_base.swap( next_base );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if ( is_tree_42 || is_tree_31 )
|
||||||
{
|
{
|
||||||
// "tree" simple reduce "42": 2->4->8->16->32->...
|
// "tree" simple reduce "42": 2->4->8->16->32->...
|
||||||
//
|
//
|
||||||
@ -3071,6 +3232,7 @@ bool StdMeshers_Quadrangle_2D::ComputeReduced (SMESH_Mesh & aMesh,
|
|||||||
} // end "linear" simple reduce
|
} // end "linear" simple reduce
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
} // end Simple Reduce implementation
|
} // end Simple Reduce implementation
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user