-// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2021 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
// 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
//
#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"
#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 <BRep_Tool.hxx>
+#include <Bnd_B3d.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
-#include <TopTools_SequenceOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
#include <TopoDS.hxx>
#include "utilities.h"
#include "Utils_ExceptHandlers.hxx"
+#include <cstddef>
+#include <numeric>
+
typedef SMESH_Comment TComm;
using namespace std;
*/
//=============================================================================
-StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId, SMESH_Gen * gen)
- :SMESH_3D_Algo(hypId, studyId, gen)
+StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, SMESH_Gen * gen)
+ :SMESH_3D_Algo(hypId, gen)
{
- MESSAGE("StdMeshers_Hexa_3D::StdMeshers_Hexa_3D");
_name = "Hexa_3D";
_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 );
}
//=============================================================================
StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D()
{
- MESSAGE("StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D");
+ delete _quadAlgo;
+ _quadAlgo = 0;
}
//=============================================================================
return false;
*/
- _viscousLayersHyp = NULL;
+ _viscousLayersHyp = nullptr;
+ _blockRenumberHyp = nullptr;
const list<const SMESHDS_Hypothesis*>& hyps =
GetUsedHypothesis(aMesh, aShape, /*ignoreAuxiliary=*/false);
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;
}
// 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<TNodeColumn> _columns;
// columns of normalized parameters of nodes within the unitary cube
//================================================================================
/*!
- * \brief Convertor of a pair of integers to a sole index
+ * \brief Converter of a pair of integers to a sole index
*/
struct _Indexer
{
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
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() ) ||
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 );
}
}
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
{
// PAL14921. Enable catching std::bad_alloc and Standard_OutOfMemory outside
//Unexpect aCatch(SalomeException);
- MESSAGE("StdMeshers_Hexa_3D::Compute");
SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
// Shape verification
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(), 0, _gen);
+ 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(), GetStudyId(), _gen);
for ( int i = 0; i < 6; ++i )
{
- if ( !( quad[i] = FaceQuadStructPtr( quadAlgo.CheckNbEdges( aMesh, FF( i+1 )))))
- 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
// --------------------
}
}
+ // 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;
// check if the loaded grid corresponds to nb of quadrangles on the FACE
const SMESHDS_SubMesh* faceSubMesh =
proxymesh ? proxymesh->GetSubMesh( F ) : meshDS->MeshElements( F );
- const int nbQuads = faceSubMesh->NbElements();
+ const smIdType nbQuads = faceSubMesh->NbElements();
const int nbHor = aCubeSide[i]._u2nodesMap.size() - 1;
const int nbVer = aCubeSide[i]._u2nodesMap.begin()->second.size() - 1;
ok = ( nbQuads == nbHor * nbVer );
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 );
_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 );
}
}
+ // 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<gp_XYZ> pointsOnShapes( SMESH_Block::ID_Shell );
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 )
{
// 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);
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
// ---------------------
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;
}
}
if (meshFaces.size() != 6) {
//return error(COMPERR_BAD_SHAPE, TComm(meshFaces.size())<<" instead of 6 faces in a block");
- static StdMeshers_CompositeHexa_3D compositeHexa(-10, 0, aMesh.GetGen());
+ static StdMeshers_CompositeHexa_3D compositeHexa(-10, aMesh.GetGen());
return compositeHexa.Evaluate(aMesh, aShape, aResMap);
}
TopoDS_Shape aFace = aFaces.Value(i+1);
SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace);
if( !algo ) {
- std::vector<int> aResVec(SMDSEntity_Last);
+ std::vector<smIdType> aResVec(SMDSEntity_Last);
for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
aResMap.insert(std::make_pair(sm,aResVec));
if (algoName == "Quadrangle_2D") {
MapShapeNbElemsItr anIt = aResMap.find(meshFaces[i]);
if( anIt == aResMap.end() ) continue;
- std::vector<int> aVec = (*anIt).second;
- int nbtri = Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]);
+ std::vector<smIdType> aVec = (*anIt).second;
+ smIdType nbtri = std::max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]);
if( nbtri == 0 )
isAllQuad = true;
}
if( sm ) {
MapShapeNbElemsItr anIt = aResMap.find(sm);
if( anIt == aResMap.end() ) continue;
- std::vector<int> aVec = (*anIt).second;
- nb1d += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]);
+ std::vector<smIdType> aVec = (*anIt).second;
+ nb1d += std::max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]);
if(IsFirst) {
IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]);
IsFirst = false;
if( i == OppNum ) continue;
MapShapeNbElemsItr anIt = aResMap.find( meshFaces[i-1] );
if( anIt == aResMap.end() ) continue;
- std::vector<int> aVec = (*anIt).second;
- nb2d += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
+ std::vector<smIdType> aVec = (*anIt).second;
+ nb2d += std::max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
}
MapShapeNbElemsItr anIt = aResMap.find( meshFaces[0] );
- std::vector<int> aVec = (*anIt).second;
- int nb2d_face0 = Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
- int nb0d_face0 = aVec[SMDSEntity_Node];
+ std::vector<smIdType> aVec = (*anIt).second;
+ smIdType nb2d_face0 = std::max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
+ smIdType nb0d_face0 = aVec[SMDSEntity_Node];
- std::vector<int> aResVec(SMDSEntity_Last);
+ std::vector<smIdType> aResVec(SMDSEntity_Last);
for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
if(IsQuadratic) {
aResVec[SMDSEntity_Quad_Hexa] = nb2d_face0 * ( nb2d/nb1d );
- int nb1d_face0_int = ( nb2d_face0*4 - nb1d ) / 2;
+ smIdType nb1d_face0_int = ( nb2d_face0*4 - nb1d ) / 2;
aResVec[SMDSEntity_Node] = nb0d_face0 * ( 2*nb2d/nb1d - 1 ) - nb1d_face0_int * nb2d/nb1d;
}
else {
static StdMeshers_HexaFromSkin_3D * algo = 0;
if ( !algo ) {
SMESH_Gen* gen = aMesh.GetGen();
- algo = new StdMeshers_HexaFromSkin_3D( gen->GetANewId(), 0, gen );
+ algo = new StdMeshers_HexaFromSkin_3D( gen->GetANewId(), gen );
}
algo->InitComputeError();
algo->Compute( aMesh, aHelper );
if ( !toCheckAll && ok ) return true;
}
return toCheckAll;
-};
+}
//=======================================================================
//function : ComputePentahedralMesh
static StdMeshers_Prism_3D * aPrism3D = 0;
if ( !aPrism3D ) {
SMESH_Gen* gen = aMesh.GetGen();
- aPrism3D = new StdMeshers_Prism_3D( gen->GetANewId(), 0, gen );
+ aPrism3D = new StdMeshers_Prism_3D( gen->GetANewId(), gen );
}
SMESH_Hypothesis::Hypothesis_Status aStatus;
if ( aPrism3D->CheckHypothesis( aMesh, aShape, aStatus ) ) {
static StdMeshers_Prism_3D * aPrism3D = 0;
if ( !aPrism3D ) {
SMESH_Gen* gen = aMesh.GetGen();
- aPrism3D = new StdMeshers_Prism_3D( gen->GetANewId(), 0, gen );
+ aPrism3D = new StdMeshers_Prism_3D( gen->GetANewId(), gen );
}
SMESH_Hypothesis::Hypothesis_Status aStatus;
if ( aPrism3D->CheckHypothesis( aMesh, aShape, aStatus ) ) {