X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_Hexa_3D.cxx;h=eeb6ad40e028aa68d42ff8927e5200cd3752870c;hp=a968121c58e6fda028db3d8c65cee8487daacbef;hb=9d0765db5d66008669b55c3388966a8de3755c92;hpb=264eeb2edd6977ccf2d2bd88cbb210353f63f7c9 diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.cxx b/src/StdMeshers/StdMeshers_Hexa_3D.cxx index a968121c5..eeb6ad40e 100644 --- a/src/StdMeshers/StdMeshers_Hexa_3D.cxx +++ b/src/StdMeshers/StdMeshers_Hexa_3D.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -20,7 +20,7 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH : implementaion of SMESH idl descriptions +// SMESH SMESH : implementation of SMESH idl descriptions // File : StdMeshers_Hexa_3D.cxx // Moved here from SMESH_Hexa_3D.cxx // Author : Paul RASCLE, EDF @@ -28,6 +28,13 @@ // #include "StdMeshers_Hexa_3D.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMESH_Comment.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_Mesh.hxx" +#include "SMESH_MesherHelper.hxx" +#include "SMESH_subMesh.hxx" +#include "StdMeshers_BlockRenumber.hxx" #include "StdMeshers_CompositeHexa_3D.hxx" #include "StdMeshers_FaceSide.hxx" #include "StdMeshers_HexaFromSkin_3D.hxx" @@ -36,23 +43,21 @@ #include "StdMeshers_Quadrangle_2D.hxx" #include "StdMeshers_ViscousLayers.hxx" -#include "SMESH_Comment.hxx" -#include "SMESH_Gen.hxx" -#include "SMESH_Mesh.hxx" -#include "SMESH_MesherHelper.hxx" -#include "SMESH_subMesh.hxx" - -#include "SMDS_MeshNode.hxx" - +#include +#include #include #include -#include #include +#include #include #include "utilities.h" #include "Utils_ExceptHandlers.hxx" +#include + +#include + typedef SMESH_Comment TComm; using namespace std; @@ -77,6 +82,8 @@ StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, SMESH_Gen * gen) _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit /shape type _requireShape = false; _compatibleHypothesis.push_back("ViscousLayers"); + _compatibleHypothesis.push_back("BlockRenumber"); + _quadAlgo = new StdMeshers_Quadrangle_2D( gen->GetANewId(), _gen ); } //============================================================================= @@ -87,6 +94,8 @@ StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, SMESH_Gen * gen) StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D() { + delete _quadAlgo; + _quadAlgo = 0; } //============================================================================= @@ -111,7 +120,8 @@ bool StdMeshers_Hexa_3D::CheckHypothesis return false; */ - _viscousLayersHyp = NULL; + _viscousLayersHyp = nullptr; + _blockRenumberHyp = nullptr; const list& hyps = GetUsedHypothesis(aMesh, aShape, /*ignoreAuxiliary=*/false); @@ -126,13 +136,25 @@ bool StdMeshers_Hexa_3D::CheckHypothesis aStatus = HYP_OK; for ( ; h != hyps.end(); ++h ) { - if ( !(_viscousLayersHyp = dynamic_cast< const StdMeshers_ViscousLayers*> ( *h ))) - break; + if ( !_viscousLayersHyp && + (_viscousLayersHyp = dynamic_cast< const StdMeshers_ViscousLayers*> ( *h ))) + continue; + if ( !_blockRenumberHyp && + (_blockRenumberHyp = dynamic_cast< const StdMeshers_BlockRenumber*> ( *h ))) + continue; + break; } - if ( !_viscousLayersHyp ) + if ((int) hyps.size() != (bool)_viscousLayersHyp + (bool)_blockRenumberHyp ) aStatus = HYP_INCOMPATIBLE; else - error( _viscousLayersHyp->CheckHypothesis( aMesh, aShape, aStatus )); + { + if ( _viscousLayersHyp ) + if ( !error( _viscousLayersHyp->CheckHypothesis( aMesh, aShape, aStatus ))) + aStatus = HYP_BAD_PARAMETER; + + if ( _blockRenumberHyp && aStatus == HYP_OK ) + error( _blockRenumberHyp->CheckHypothesis( aMesh, aShape )); + } return aStatus == HYP_OK; } @@ -164,7 +186,7 @@ namespace // map of (node parameter on EDGE) to (column (vector) of nodes) TParam2ColumnMap _u2nodesMap; - // node column's taken form _u2nodesMap taking into account sub-shape orientation + // node column's taken from _u2nodesMap taking into account sub-shape orientation vector _columns; // columns of normalized parameters of nodes within the unitary cube @@ -189,7 +211,7 @@ namespace //================================================================================ /*! - * \brief Convertor of a pair of integers to a sole index + * \brief Converter of a pair of integers to a sole index */ struct _Indexer { @@ -199,26 +221,6 @@ namespace int operator()(const int x, const int y) const { return y * _xSize + x; } }; - //================================================================================ - /*! - * \brief Appends a range of node columns from a map to another map - */ - template< class TMapIterator > - void append( TParam2ColumnMap& toMap, TMapIterator from, TMapIterator to ) - { - const SMDS_MeshNode* lastNode = toMap.rbegin()->second[0]; - const SMDS_MeshNode* firstNode = from->second[0]; - if ( lastNode == firstNode ) - from++; - double u = toMap.rbegin()->first; - for (; from != to; ++from ) - { - u += 1; - TParam2ColumnMap::iterator u2nn = toMap.insert( toMap.end(), make_pair ( u, TNodeColumn())); - u2nn->second.swap( from->second ); - } - } - //================================================================================ /*! * \brief Finds FaceQuadStruct having a side equal to a given one and rearranges @@ -231,7 +233,7 @@ namespace for ( int i = 1; i < 6; ++i ) { if ( !quad[i] ) continue; - for ( unsigned iS = 0; iS < quad[i]->side.size(); ++iS ) + for ( size_t iS = 0; iS < quad[i]->side.size(); ++iS ) { const StdMeshers_FaceSidePtr side2 = quad[i]->side[iS]; if (( side->FirstVertex().IsSame( side2->FirstVertex() ) || @@ -244,9 +246,9 @@ namespace if ( iS != Q_BOTTOM ) { vector< FaceQuadStruct::Side > newSides; - for ( unsigned j = iS; j < quad[i]->side.size(); ++j ) + for ( size_t j = iS; j < quad[i]->side.size(); ++j ) newSides.push_back( quad[i]->side[j] ); - for ( unsigned j = 0; j < iS; ++j ) + for ( size_t j = 0; j < iS; ++j ) newSides.push_back( quad[i]->side[j] ); quad[i]->side.swap( newSides ); } @@ -257,6 +259,204 @@ namespace } return foundQuad; } + + //================================================================================ + /*! + * \brief Put quads to aCubeSide in the order of enum EBoxSides + */ + //================================================================================ + + bool arrangeQuads( FaceQuadStructPtr quad[ 6 ], _FaceGrid aCubeSide[ 6 ], bool reverseBottom ) + { + swap( aCubeSide[B_BOTTOM]._quad, quad[0] ); + if ( reverseBottom ) + swap( aCubeSide[B_BOTTOM]._quad->side[ Q_RIGHT],// direct the bottom normal inside cube + aCubeSide[B_BOTTOM]._quad->side[ Q_LEFT ] ); + + aCubeSide[B_FRONT]._quad = getQuadWithBottom( aCubeSide[B_BOTTOM]._quad->side[Q_BOTTOM], quad ); + aCubeSide[B_RIGHT]._quad = getQuadWithBottom( aCubeSide[B_BOTTOM]._quad->side[Q_RIGHT ], quad ); + aCubeSide[B_BACK ]._quad = getQuadWithBottom( aCubeSide[B_BOTTOM]._quad->side[Q_TOP ], quad ); + aCubeSide[B_LEFT ]._quad = getQuadWithBottom( aCubeSide[B_BOTTOM]._quad->side[Q_LEFT ], quad ); + if ( aCubeSide[B_FRONT ]._quad ) + aCubeSide[B_TOP]._quad = getQuadWithBottom( aCubeSide[B_FRONT ]._quad->side[Q_TOP ], quad ); + + for ( int i = 1; i < 6; ++i ) + if ( !aCubeSide[i]._quad ) + return false; + return true; + } + + //================================================================================ + /*! + * \brief Rearrange block sides according to StdMeshers_BlockRenumber hypothesis + */ + //================================================================================ + + bool arrangeForRenumber( _FaceGrid blockSide[ 6 ], + TopoDS_Vertex& v000, + TopoDS_Vertex& v001 ) + { + std::swap( blockSide[B_BOTTOM]._quad->side[ Q_RIGHT],// restore after arrangeQuads() + blockSide[B_BOTTOM]._quad->side[ Q_LEFT ] ); + + // find v000 + TopTools_MapOfShape cornerVertices; + cornerVertices.Add( blockSide[B_BOTTOM]._quad->side[Q_BOTTOM].grid->LastVertex() ); + cornerVertices.Add( blockSide[B_BOTTOM]._quad->side[Q_BOTTOM].grid->FirstVertex() ); + cornerVertices.Add( blockSide[B_BOTTOM]._quad->side[Q_TOP ].grid->LastVertex() ); + cornerVertices.Add( blockSide[B_BOTTOM]._quad->side[Q_TOP ].grid->FirstVertex() ); + cornerVertices.Add( blockSide[B_TOP ]._quad->side[Q_BOTTOM].grid->FirstVertex() ); + cornerVertices.Add( blockSide[B_TOP ]._quad->side[Q_BOTTOM].grid->LastVertex() ); + cornerVertices.Add( blockSide[B_TOP ]._quad->side[Q_TOP ].grid->FirstVertex() ); + cornerVertices.Add( blockSide[B_TOP ]._quad->side[Q_TOP ].grid->LastVertex() ); + + if ( v000.IsNull() ) + { + // block CS is not defined; + // renumber only if the block has an edge parallel to an axis of global CS + + v000 = StdMeshers_RenumberHelper::GetVertex000( cornerVertices ); + } + + Bnd_B3d bbox; + for ( auto it = cornerVertices.cbegin(); it != cornerVertices.cend(); ++it ) + bbox.Add( BRep_Tool::Pnt( TopoDS::Vertex( *it ))); + double tol = 1e-5 * Sqrt( bbox.SquareExtent() ); + + // get block edges starting at v000 + + std::vector< StdMeshers_FaceSidePtr > edgesAtV000; + std::vector< gp_Vec > edgeDir; + std::vector< int > iParallel; // 0 - none, 1 - X, 2 - Y, 3 - Z + TopTools_MapOfShape lastVertices; + for ( int iQ = 0; iQ < 6; ++iQ ) + { + FaceQuadStructPtr quad = blockSide[iQ]._quad; + for ( size_t iS = 0; iS < quad->side.size() && edgesAtV000.size() < 3; ++iS ) + { + StdMeshers_FaceSidePtr edge = quad->side[iS]; + TopoDS_Vertex v1 = edge->FirstVertex(), v2 = edge->LastVertex(); + if (( v1.IsSame( v000 ) && !lastVertices.Contains( v2 )) || + ( v2.IsSame( v000 ) && !lastVertices.Contains( v1 ))) + { + bool reverse = v2.IsSame( v000 ); + if ( reverse ) + std::swap( v1, v2 ); + lastVertices.Add( v2 ); + + edgesAtV000.push_back( edge ); + + gp_Pnt pf = BRep_Tool::Pnt( v1 ); + gp_Pnt pl = BRep_Tool::Pnt( v2 ); + gp_Vec vec( pf, pl ); + edgeDir.push_back( vec ); + + iParallel.push_back( 0 ); + if ( !v001.IsNull() ) + { + if ( v001.IsSame( v2 )) + iParallel.back() = 3; + } + else + { + bool isStraight = true; + for ( int iE = 0; iE < edge->NbEdges() && isStraight; ++iE ) + isStraight = SMESH_Algo::IsStraight( edge->Edge( iE )); + + // is parallel to a GCS axis? + if ( isStraight ) + { + int nbDiff = (( Abs( vec.X() ) > tol ) + + ( Abs( vec.Y() ) > tol ) + + ( Abs( vec.Z() ) > tol ) ); + if ( nbDiff == 1 ) + iParallel.back() = ( Abs( vec.X() ) > tol ) ? 1 : ( Abs( vec.Y() ) > tol ) ? 2 : 3; + } + else + { + edgeDir.back() = gp_Vec( pf, edge->Value3d( reverse ? 0.99 : 0.01 )); + } + } + } + } + } + if ( std::accumulate( iParallel.begin(), iParallel.end(), 0 ) == 0 ) + return false; + + // find edge OZ and edge OX + StdMeshers_FaceSidePtr edgeOZ, edgeOX; + auto iZIt = std::find( iParallel.begin(), iParallel.end(), 3 ); + if ( iZIt != iParallel.end() ) + { + int i = std::distance( iParallel.begin(), iZIt ); + edgeOZ = edgesAtV000[ i ]; + int iE1 = SMESH_MesherHelper::WrapIndex( i + 1, edgesAtV000.size() ); + int iE2 = SMESH_MesherHelper::WrapIndex( i + 2, edgesAtV000.size() ); + if (( edgeDir[ iE1 ] ^ edgeDir[ iE2 ] ) * edgeDir[ i ] < 0 ) + std::swap( iE1, iE2 ); + edgeOX = edgesAtV000[ iE1 ]; + } + else + { + for ( size_t i = 0; i < edgesAtV000.size(); ++i ) + { + if ( !iParallel[ i ] ) + continue; + int iE1 = SMESH_MesherHelper::WrapIndex( i + 1, edgesAtV000.size() ); + int iE2 = SMESH_MesherHelper::WrapIndex( i + 2, edgesAtV000.size() ); + if (( edgeDir[ iE1 ] ^ edgeDir[ iE2 ] ) * edgeDir[ i ] < 0 ) + std::swap( iE1, iE2 ); + edgeOZ = edgesAtV000[ iParallel[i] == 1 ? iE2 : iE1 ]; + edgeOX = edgesAtV000[ iParallel[i] == 1 ? i : iE1 ]; + break; + } + } + + if ( !edgeOZ || !edgeOX ) + return false; + + TopoDS_Vertex v100 = edgeOX->LastVertex(); + if ( v100.IsSame( v000 )) + v100 = edgeOX->FirstVertex(); + + // Find the left quad, one including v000 but not v100 + + for ( int iQ = 0; iQ < 6; ++iQ ) + { + FaceQuadStructPtr quad = blockSide[iQ]._quad; + bool hasV000 = false, hasV100 = false; + for ( size_t iS = 0; iS < quad->side.size(); ++iS ) + { + StdMeshers_FaceSidePtr edge = quad->side[iS]; + if ( edge->FirstVertex().IsSame( v000 ) || edge->LastVertex().IsSame( v000 )) + hasV000 = true; + if ( edge->FirstVertex().IsSame( v100 ) || edge->LastVertex().IsSame( v100 )) + hasV100 = true; + } + if ( hasV000 && !hasV100 ) + { + // orient the left quad + for ( int i = 0; i < 4; ++i ) + { + if ( quad->side[Q_BOTTOM].grid->Edge(0).IsSame( edgeOZ->Edge(0) )) + break; + quad->shift( 1, true ); + } + + FaceQuadStructPtr quads[ 6 ]; + quads[0].swap( blockSide[iQ]._quad ); + for ( int i = 1, j = 0; i < 6; ++i, ++j ) + if ( blockSide[ j ]._quad ) + quads[ i ].swap( blockSide[ j ]._quad ); + else + --i; + + return arrangeQuads( quads, blockSide, false/* true*/ ); + } + } + return false; + } + //================================================================================ /*! * \brief Returns true if the 1st base node of sideGrid1 belongs to sideGrid2 @@ -363,46 +563,46 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, if ( exp.Next(), exp.More() ) return error(COMPERR_BAD_SHAPE, "More than one SHELL in the geometry"); - TopTools_IndexedMapOfShape FF; + TopTools_IndexedMapOfShape FF, EE; TopExp::MapShapes( aShape, TopAbs_FACE, FF); if ( FF.Extent() != 6) { static StdMeshers_CompositeHexa_3D compositeHexa(_gen->GetANewId(), _gen); + compositeHexa.SetHypothesis( _blockRenumberHyp ); if ( !compositeHexa.Compute( aMesh, aShape )) return error( compositeHexa.GetComputeError() ); - return true; + + return _blockRenumberHyp ? error( _blockRenumberHyp->CheckHypothesis( aMesh, aShape )) : true; } // Find sides of a cube // --------------------- - + + // tool creating quadratic elements if needed + SMESH_MesherHelper helper (aMesh); + _quadraticMesh = helper.IsQuadraticSubMesh(aShape); + + TopExp::MapShapes( aShape, TopAbs_EDGE, EE ); + SMESH_MesherHelper* faceHelper = ( EE.Size() == 12 ) ? 0 : &helper; + FaceQuadStructPtr quad[ 6 ]; - StdMeshers_Quadrangle_2D quadAlgo( _gen->GetANewId(), _gen); for ( int i = 0; i < 6; ++i ) { - if ( !( quad[i] = FaceQuadStructPtr( quadAlgo.CheckNbEdges( aMesh, FF( i+1 ), - /*considerMesh=*/true)))) - return error( quadAlgo.GetComputeError() ); + if ( faceHelper ) + faceHelper->SetSubShape( FF( i+1 )); + if ( !( quad[i] = FaceQuadStructPtr( _quadAlgo->CheckNbEdges( aMesh, FF( i+1 ), + /*considerMesh=*/true, + faceHelper)))) + return error( _quadAlgo->GetComputeError() ); if ( quad[i]->side.size() != 4 ) return error( COMPERR_BAD_SHAPE, "Not a quadrangular box side" ); } + // put quads in a proper order _FaceGrid aCubeSide[ 6 ]; + if ( !arrangeQuads( quad, aCubeSide, true )) + return error( COMPERR_BAD_SHAPE ); - swap( aCubeSide[B_BOTTOM]._quad, quad[0] ); - swap( aCubeSide[B_BOTTOM]._quad->side[ Q_RIGHT],// direct the normal of bottom quad inside cube - aCubeSide[B_BOTTOM]._quad->side[ Q_LEFT ] ); - - aCubeSide[B_FRONT]._quad = getQuadWithBottom( aCubeSide[B_BOTTOM]._quad->side[Q_BOTTOM], quad ); - aCubeSide[B_RIGHT]._quad = getQuadWithBottom( aCubeSide[B_BOTTOM]._quad->side[Q_RIGHT ], quad ); - aCubeSide[B_BACK ]._quad = getQuadWithBottom( aCubeSide[B_BOTTOM]._quad->side[Q_TOP ], quad ); - aCubeSide[B_LEFT ]._quad = getQuadWithBottom( aCubeSide[B_BOTTOM]._quad->side[Q_LEFT ], quad ); - if ( aCubeSide[B_FRONT ]._quad ) - aCubeSide[B_TOP]._quad = getQuadWithBottom( aCubeSide[B_FRONT ]._quad->side[Q_TOP ], quad ); - - for ( int i = 1; i < 6; ++i ) - if ( !aCubeSide[i]._quad ) - return error( COMPERR_BAD_SHAPE ); // Make viscous layers // -------------------- @@ -434,13 +634,25 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, } } + // Arrange sides according to _blockRenumberHyp + bool toRenumber = _blockRenumberHyp; + if ( toRenumber ) + { + TopoDS_Vertex v000, v001; + _blockRenumberHyp->IsSolidIncluded( aMesh, aShape, v000, v001 ); + + toRenumber = arrangeForRenumber( aCubeSide, v000, v001 ); + + if ( toRenumber ) + { + meshDS->Modified(); + meshDS->CompactMesh(); // remove numbering holes + } + } + // Check presence of regular grid mesh on FACEs of the cube // ------------------------------------------------------------ - // tool creating quadratic elements if needed - SMESH_MesherHelper helper (aMesh); - _quadraticMesh = helper.IsQuadraticSubMesh(aShape); - for ( int i = 0; i < 6; ++i ) { const TopoDS_Face& F = aCubeSide[i]._quad->face; @@ -513,8 +725,8 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, if ( proxymesh ) for ( int i = 0; i < 6; ++i ) - for ( unsigned j = 0; j < aCubeSide[i]._columns.size(); ++j) - for ( unsigned k = 0; k < aCubeSide[i]._columns[j].size(); ++k) + for ( size_t j = 0; j < aCubeSide[i]._columns.size(); ++j) + for ( size_t k = 0; k < aCubeSide[i]._columns[j].size(); ++k) { const SMDS_MeshNode* & n = aCubeSide[i]._columns[j][k]; n = proxymesh->GetProxyNode( n ); @@ -534,18 +746,24 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, _FaceGrid* fFront = & aCubeSide[ B_FRONT ]; _FaceGrid* fBack = & aCubeSide[ B_BACK ]; - // compute normalized parameters of nodes on sides (PAL23189) - computeIJK( *fBottom, COO_X, COO_Y, /*z=*/0. ); - computeIJK( *fRight, COO_Y, COO_Z, /*x=*/1. ); - computeIJK( *fTop, COO_X, COO_Y, /*z=*/1. ); - computeIJK( *fLeft, COO_Y, COO_Z, /*x=*/0. ); - computeIJK( *fFront, COO_X, COO_Z, /*y=*/0. ); - computeIJK( *fBack, COO_X, COO_Z, /*y=*/1. ); - // cube size measured in nb of nodes - int x, xSize = fBottom->_columns.size() , X = xSize - 1; - int y, ySize = fLeft->_columns.size() , Y = ySize - 1; - int z, zSize = fLeft->_columns[0].size(), Z = zSize - 1; + size_t x, xSize = fBottom->_columns.size() , X = xSize - 1; + size_t y, ySize = fLeft->_columns.size() , Y = ySize - 1; + size_t z, zSize = fLeft->_columns[0].size(), Z = zSize - 1; + + // check sharing of FACEs (IPAL54417) + if ( fFront ->_columns.size() != xSize || + fBack ->_columns.size() != xSize || + fTop ->_columns.size() != xSize || + + fRight ->_columns.size() != ySize || + fTop ->_columns[0].size() != ySize || + fBottom->_columns[0].size() != ySize || + + fRight ->_columns[0].size() != zSize || + fFront ->_columns[0].size() != zSize || + fBack ->_columns[0].size() != zSize ) + return error( COMPERR_BAD_SHAPE, "Not sewed faces" ); // columns of internal nodes "rising" from nodes of fBottom _Indexer colIndex( xSize, ySize ); @@ -583,6 +801,16 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, } } + // compute normalized parameters of nodes on sides (PAL23189) + computeIJK( *fBottom, COO_X, COO_Y, /*z=*/0. ); + computeIJK( *fRight, COO_Y, COO_Z, /*x=*/1. ); + computeIJK( *fTop, COO_X, COO_Y, /*z=*/1. ); + computeIJK( *fLeft, COO_Y, COO_Z, /*x=*/0. ); + computeIJK( *fFront, COO_X, COO_Z, /*y=*/0. ); + computeIJK( *fBack, COO_X, COO_Z, /*y=*/1. ); + + StdMeshers_RenumberHelper renumHelper( aMesh, _blockRenumberHyp ); + // projection points of the internal node on cube sub-shapes by which // coordinates of the internal node are computed vector pointsOnShapes( SMESH_Block::ID_Shell ); @@ -598,8 +826,24 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, pointsOnShapes[ SMESH_Block::ID_V111 ] = fTop->GetXYZ( X, Y ); gp_XYZ params; // normalized parameters of an internal node within the unit box + + if ( toRenumber ) + for ( y = 0; y < ySize; ++y ) + { + vector< const SMDS_MeshNode* >& column0y = columns[ colIndex( 0, y )]; + for ( z = 0; z < zSize; ++z ) + renumHelper.AddReplacingNode( column0y[ z ] ); + } + for ( x = 1; x < xSize-1; ++x ) { + if ( toRenumber ) + { + vector< const SMDS_MeshNode* >& columnX0 = columns[ colIndex( x, 0 )]; + for ( z = 0; z < zSize; ++z ) + renumHelper.AddReplacingNode( columnX0[ z ] ); + } + const double rX = x / double(X); for ( y = 1; y < ySize-1; ++y ) { @@ -619,6 +863,10 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, // projection points on horizontal faces pointsOnShapes[ SMESH_Block::ID_Fxy0 ] = fBottom->GetXYZ( x, y ); pointsOnShapes[ SMESH_Block::ID_Fxy1 ] = fTop ->GetXYZ( x, y ); + + if ( toRenumber ) + renumHelper.AddReplacingNode( column[ 0 ] ); + for ( z = 1; z < zSize-1; ++z ) // z loop { const double rZ = z / double(Z); @@ -651,13 +899,31 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, gp_XYZ coords; SMESH_Block::ShellPoint( params, pointsOnShapes, coords ); column[ z ] = helper.AddNode( coords.X(), coords.Y(), coords.Z() ); - } + + } // z loop + if ( toRenumber ) + renumHelper.AddReplacingNode( column[ Z ] ); + + } // y loop + if ( toRenumber ) + { + vector< const SMDS_MeshNode* >& columnX0 = columns[ colIndex( x, Y )]; + for ( z = 0; z < zSize; ++z ) + renumHelper.AddReplacingNode( columnX0[ z ] ); + } + } // x loop + + if ( toRenumber ) + for ( y = 0; y < ySize; ++y ) + { + vector< const SMDS_MeshNode* >& columnXy = columns[ colIndex( X, y )]; + for ( z = 0; z < zSize; ++z ) + renumHelper.AddReplacingNode( columnXy[ z ] ); } - } // side data no more needed, free memory for ( int i = 0; i < 6; ++i ) - aCubeSide[i]._columns.clear(); + SMESHUtils::FreeVector( aCubeSide[i]._columns ); // 5) Create hexahedrons // --------------------- @@ -671,11 +937,25 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, for ( z = 0; z < zSize-1; ++z ) { // bottom face normal of a hexa mush point outside the volume - helper.AddVolume(col00[z], col01[z], col11[z], col10[z], - col00[z+1], col01[z+1], col11[z+1], col10[z+1]); + if ( toRenumber ) + helper.AddVolume(col00[z], col01[z], col01[z+1], col00[z+1], + col10[z], col11[z], col11[z+1], col10[z+1]); + else + helper.AddVolume(col00[z], col01[z], col11[z], col10[z], + col00[z+1], col01[z+1], col11[z+1], col10[z+1]); } } } + + if ( toRenumber ) + renumHelper.DoReplaceNodes(); + + + if ( _blockRenumberHyp ) + { + return error( _blockRenumberHyp->CheckHypothesis( aMesh, aShape )); + } + return true; }