mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-03-27 17:58:35 +05:00
618 lines
21 KiB
C++
618 lines
21 KiB
C++
// Copyright (C) 2007-2024 CEA, EDF, OPEN CASCADE
|
|
//
|
|
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
|
|
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
|
|
//
|
|
// This library is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
// License as published by the Free Software Foundation; either
|
|
// version 2.1 of the License, or (at your option) any later version.
|
|
//
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
// License along with this library; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
//
|
|
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
|
//
|
|
|
|
// File : StdMeshers_PolyhedronPerSolid_3D.cxx
|
|
// Module : SMESH
|
|
// Created : Fri Oct 20 11:37:07 2006
|
|
// Author : Edward AGAPOV (eap)
|
|
//
|
|
#include "StdMeshers_PolyhedronPerSolid_3D.hxx"
|
|
|
|
#include "SMESHDS_Mesh.hxx"
|
|
#include "SMESH_ControlsDef.hxx"
|
|
#include "SMESH_Gen.hxx"
|
|
#include "SMESH_Mesh.hxx"
|
|
#include "SMESH_MeshAlgos.hxx"
|
|
#include "SMESH_MeshEditor.hxx"
|
|
#include "SMESH_MesherHelper.hxx"
|
|
#include "SMESH_ProxyMesh.hxx"
|
|
#include "SMESH_subMesh.hxx"
|
|
#include "StdMeshers_PolygonPerFace_2D.hxx"
|
|
#include "StdMeshers_Regular_1D.hxx"
|
|
#include "StdMeshers_ViscousLayers.hxx"
|
|
|
|
#include <TopExp_Explorer.hxx>
|
|
|
|
#include <vector>
|
|
#include <set>
|
|
|
|
namespace
|
|
{
|
|
struct _EdgeMesher : public StdMeshers_Regular_1D
|
|
{
|
|
_EdgeMesher( int hypId, SMESH_Gen* gen )
|
|
: StdMeshers_Regular_1D( hypId, gen )
|
|
{
|
|
_hypType = NB_SEGMENTS;
|
|
_ivalue[ NB_SEGMENTS_IND ] = 1;
|
|
}
|
|
};
|
|
|
|
//=======================================================================
|
|
//function : addHexa
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
const SMDS_MeshElement* addHexa( std::vector< const SMDS_MeshElement* >& faces,
|
|
const std::vector< int > & quantities,
|
|
SMESH_MesherHelper & helper )
|
|
{
|
|
const SMDS_MeshElement* newHexa = 0;
|
|
|
|
// check nb of nodes in faces
|
|
for ( size_t i = 0; i < quantities.size(); ++i )
|
|
if ( quantities[ i ] != 4 )
|
|
return newHexa;
|
|
|
|
// look for a top face
|
|
const SMDS_MeshElement* topFace = 0;
|
|
const SMDS_MeshElement* botFace = faces[0];
|
|
std::vector< const SMDS_MeshNode* > nodes( 16 ); // last 8 is a working buffer
|
|
nodes.assign( botFace->begin_nodes(), botFace->end_nodes() );
|
|
for ( size_t iF = 1; iF < faces.size() && !topFace; ++iF )
|
|
{
|
|
bool hasCommonNode = false;
|
|
for ( int iN = 0; iN < quantities[ 0 ] && !hasCommonNode; ++iN )
|
|
hasCommonNode = ( faces[ iF ]->GetNodeIndex( nodes[ iN ]) >= 0 );
|
|
|
|
if ( !hasCommonNode )
|
|
topFace = faces[ iF ];
|
|
}
|
|
|
|
nodes.resize( 8 ); // set top nodes after hexa nodes - [8-11]
|
|
nodes.insert( nodes.end(), topFace->begin_nodes(), topFace->end_nodes() );
|
|
nodes.resize( 12 );
|
|
nodes.insert( nodes.end(), nodes.begin() + 8, nodes.begin() + 12 );
|
|
|
|
// find corresponding nodes of top and bottom by finding a side face including 2 node of each
|
|
SMESHDS_Mesh* mesh = helper.GetMeshDS();
|
|
const SMDS_MeshElement* sideFace = 0;
|
|
size_t i;
|
|
for ( i = 8; i < nodes.size()-1 && !sideFace; ++i )
|
|
{
|
|
sideFace = mesh->FindFace( nodes[0], nodes[1], nodes[ i ], nodes[ i + 1 ]);
|
|
}
|
|
if ( !sideFace )
|
|
return newHexa;
|
|
|
|
--i; // restore after ++i in the loop
|
|
bool botOriRight = SMESH_MeshAlgos::IsRightOrder( sideFace, nodes[ 0 ], nodes[ 1 ] );
|
|
bool topOriRight = SMESH_MeshAlgos::IsRightOrder( sideFace, nodes[ i ], nodes[ i + 1 ] );
|
|
if ( botOriRight == topOriRight )
|
|
{
|
|
nodes[ 4 ] = nodes[ i + 1 ];
|
|
nodes[ 5 ] = nodes[ i + 0 ];
|
|
nodes[ 6 ] = nodes[ i + 3 ];
|
|
nodes[ 7 ] = nodes[ i + 2 ];
|
|
}
|
|
else
|
|
{
|
|
nodes[ 4 ] = nodes[ i + 0 ];
|
|
nodes[ 5 ] = nodes[ i + 1 ];
|
|
nodes[ 6 ] = nodes[ i + 2 ];
|
|
nodes[ 7 ] = nodes[ i + 3 ];
|
|
}
|
|
|
|
newHexa = helper.AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ],
|
|
nodes[ 4 ], nodes[ 5 ], nodes[ 6 ], nodes[ 7 ]);
|
|
|
|
return newHexa;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : addTetra
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
const SMDS_MeshElement* addTetra( std::vector< const SMDS_MeshElement* >& faces,
|
|
const std::vector< int > & quantities,
|
|
SMESH_MesherHelper & helper )
|
|
{
|
|
const SMDS_MeshElement* newTetra = 0;
|
|
|
|
// check nb of nodes in faces
|
|
for ( size_t i = 0; i < quantities.size(); ++i )
|
|
if ( quantities[ i ] != 3 )
|
|
return newTetra;
|
|
|
|
const SMDS_MeshElement* botFace = faces[0];
|
|
|
|
std::vector< const SMDS_MeshNode* > nodes( 6 );
|
|
nodes.assign( botFace->begin_nodes(), botFace->end_nodes() );
|
|
nodes.resize( 3 );
|
|
|
|
const SMDS_MeshNode* topNode = 0;
|
|
for ( size_t i = 0; i < 3 && !topNode; ++i )
|
|
{
|
|
topNode = faces[ 1 ]->GetNode( i );
|
|
if ( botFace->GetNodeIndex( topNode ) >= 0 )
|
|
topNode = 0;
|
|
}
|
|
if ( !topNode )
|
|
return newTetra;
|
|
|
|
nodes.push_back( topNode );
|
|
|
|
newTetra = helper.AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ]);
|
|
|
|
return newTetra;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : addPenta
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
const SMDS_MeshElement* addPenta( std::vector< const SMDS_MeshElement* >& faces,
|
|
const std::vector< int > & quantities,
|
|
SMESH_MesherHelper & helper )
|
|
{
|
|
const SMDS_MeshElement* newPenta = 0;
|
|
|
|
// check nb of nodes in faces and find triangle faces
|
|
int trias[2] = { -1, -1 };
|
|
for ( size_t i = 0; i < quantities.size(); ++i )
|
|
if ( quantities[ i ] != 4 )
|
|
{
|
|
if ( quantities[ i ] != 3 )
|
|
return newPenta;
|
|
int iTria = ( trias[0] != -1 );
|
|
if ( trias[ iTria ] != -1 )
|
|
return newPenta;
|
|
trias[ iTria ] = i;
|
|
}
|
|
if ( trias[1] == -1 )
|
|
return newPenta;
|
|
|
|
int iSide = trias[0] + 1;
|
|
if ( iSide == trias[1] )
|
|
++iSide;
|
|
if (iSide == 5)
|
|
// use first side (otherwise, out of bounds)
|
|
iSide = 0;
|
|
|
|
const SMDS_MeshElement* botFace = faces[ trias[0]];
|
|
const SMDS_MeshElement* topFace = faces[ trias[1]];
|
|
const SMDS_MeshElement* sideFace = faces[ iSide ];
|
|
const SMDS_MeshNode* nodes[ 6 ] = { 0,0,0,0,0,0 };
|
|
for ( int i = 0 ; i < 3; ++i )
|
|
{
|
|
const SMDS_MeshNode* botNode = botFace->GetNode( i );
|
|
if ( sideFace->GetNodeIndex( botNode ) < 0 )
|
|
nodes[2] = botNode;
|
|
else
|
|
nodes[ bool( nodes[0] )] = botNode;
|
|
|
|
const SMDS_MeshNode* topNode = topFace->GetNode( i );
|
|
if ( sideFace->GetNodeIndex( topNode ) < 0 )
|
|
nodes[5] = topNode;
|
|
else
|
|
nodes[ 3 + bool( nodes[3]) ] = topNode;
|
|
}
|
|
bool botOriRight = SMESH_MeshAlgos::IsRightOrder( sideFace, nodes[ 0 ], nodes[ 1 ]);
|
|
bool topOriRight = SMESH_MeshAlgos::IsRightOrder( sideFace, nodes[ 3 ], nodes[ 4 ]);
|
|
if ( botOriRight == topOriRight )
|
|
std::swap( nodes[ 3 ], nodes[ 4 ]);
|
|
|
|
newPenta = helper.AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ],
|
|
nodes[ 3 ], nodes[ 4 ], nodes[ 5 ]);
|
|
|
|
return newPenta;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : addPyra
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
const SMDS_MeshElement* addPyra( std::vector< const SMDS_MeshElement* >& faces,
|
|
const std::vector< int > & quantities,
|
|
SMESH_MesherHelper & helper )
|
|
{
|
|
const SMDS_MeshElement* newPyra = 0;
|
|
|
|
// check nb of nodes in faces
|
|
int iBot = -1;
|
|
for ( size_t i = 0; i < quantities.size(); ++i )
|
|
if ( quantities[ i ] != 3 )
|
|
{
|
|
if ( quantities[ i ] != 4 || iBot != -1 )
|
|
return newPyra;
|
|
iBot = i;
|
|
}
|
|
|
|
const SMDS_MeshElement* botFace = faces[ iBot ];
|
|
|
|
std::vector< const SMDS_MeshNode* > nodes( 8 );
|
|
nodes.assign( botFace->begin_nodes(), botFace->end_nodes() );
|
|
nodes.resize( 4 );
|
|
|
|
const SMDS_MeshNode* topNode = 0;
|
|
for ( size_t i = 0; i < 4 && !topNode; ++i )
|
|
{
|
|
topNode = faces[ 1 ]->GetNode( i );
|
|
if ( botFace->GetNodeIndex( topNode ) >= 0 )
|
|
topNode = 0;
|
|
}
|
|
if ( !topNode )
|
|
return newPyra;
|
|
|
|
nodes.push_back( topNode );
|
|
|
|
newPyra = helper.AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ], nodes[4] );
|
|
|
|
return newPyra;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : addHPrism
|
|
//purpose : add hexagonal prism
|
|
//=======================================================================
|
|
|
|
const SMDS_MeshElement* addHPrism( std::vector< const SMDS_MeshElement* >& faces,
|
|
const std::vector< int > & quantities,
|
|
SMESH_MesherHelper & helper )
|
|
{
|
|
const SMDS_MeshElement* newHexPrism = 0;
|
|
|
|
// check nb of nodes in faces and find hexagons
|
|
int hexa[2] = { -1, -1 };
|
|
for ( size_t i = 0; i < quantities.size(); ++i )
|
|
if ( quantities[ i ] != 4 )
|
|
{
|
|
if ( quantities[ i ] != 6 )
|
|
return newHexPrism;
|
|
int iHex = ( hexa[0] != -1 );
|
|
if ( hexa[ iHex ] != -1 )
|
|
return newHexPrism;
|
|
hexa[ iHex ] = i;
|
|
}
|
|
if ( hexa[1] == -1 )
|
|
return newHexPrism;
|
|
|
|
const SMDS_MeshElement* botFace = faces[ hexa[ 0 ]];
|
|
const SMDS_MeshElement* topFace = faces[ hexa[ 1 ]];
|
|
std::vector< const SMDS_MeshNode* > nodes( 24 ); // last 12 is a working buffer
|
|
|
|
nodes.assign( botFace->begin_nodes(), botFace->end_nodes() );
|
|
nodes.resize( 12 ); // set top nodes after hexa nodes - [12-17]
|
|
nodes.insert( nodes.end(), topFace->begin_nodes(), topFace->end_nodes() );
|
|
nodes.resize( 18 );
|
|
nodes.insert( nodes.end(), nodes.begin() + 12, nodes.begin() + 18 );
|
|
|
|
// find corresponding nodes of top and bottom by finding a side face including 2 node of each
|
|
SMESHDS_Mesh* mesh = helper.GetMeshDS();
|
|
const SMDS_MeshElement* sideFace = 0;
|
|
size_t i;
|
|
for ( i = 12; i < nodes.size()-1 && !sideFace; ++i )
|
|
{
|
|
sideFace = mesh->FindFace( nodes[0], nodes[1], nodes[ i ], nodes[ i + 1 ]);
|
|
}
|
|
if ( !sideFace )
|
|
return newHexPrism;
|
|
|
|
--i; // restore after ++i in the loop
|
|
bool botOriRight = SMESH_MeshAlgos::IsRightOrder( sideFace, nodes[ 0 ], nodes[ 1 ] );
|
|
bool topOriRight = SMESH_MeshAlgos::IsRightOrder( sideFace, nodes[ i ], nodes[ i + 1 ] );
|
|
if ( botOriRight == topOriRight )
|
|
{
|
|
nodes[ 6 ] = nodes[ i + 1 ];
|
|
nodes[ 7 ] = nodes[ i + 0 ];
|
|
nodes[ 8 ] = nodes[ i + 5 ];
|
|
nodes[ 9 ] = nodes[ i + 4 ];
|
|
nodes[ 10 ] = nodes[ i + 3 ];
|
|
nodes[ 11 ] = nodes[ i + 2 ];
|
|
}
|
|
else
|
|
{
|
|
nodes[ 6 ] = nodes[ i + 0 ];
|
|
nodes[ 7 ] = nodes[ i + 1 ];
|
|
nodes[ 8 ] = nodes[ i + 2 ];
|
|
nodes[ 9 ] = nodes[ i + 3 ];
|
|
nodes[ 10 ] = nodes[ i + 4 ];
|
|
nodes[ 11 ] = nodes[ i + 5 ];
|
|
}
|
|
|
|
newHexPrism = helper.AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ],
|
|
nodes[ 3 ], nodes[ 4 ], nodes[ 5 ],
|
|
nodes[ 6 ], nodes[ 7 ], nodes[ 8 ],
|
|
nodes[ 9 ], nodes[10 ], nodes[11 ]);
|
|
|
|
return newHexPrism;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : addPoly
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
const SMDS_MeshElement* addPoly( std::vector< const SMDS_MeshElement* >& faces,
|
|
const std::vector< int > & quantities,
|
|
SMESH_MesherHelper & helper )
|
|
{
|
|
const SMDS_MeshElement* newPoly = 0;
|
|
|
|
std::vector< const SMDS_MeshNode* > nodes;
|
|
for ( size_t iF = 0; iF < faces.size(); ++iF )
|
|
nodes.insert( nodes.end(), faces[iF]->begin_nodes(), faces[iF]->end_nodes() );
|
|
|
|
newPoly = helper.AddPolyhedralVolume( nodes, quantities );
|
|
|
|
return newPoly;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
//=======================================================================
|
|
//function : StdMeshers_PolyhedronPerSolid_3D
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
StdMeshers_PolyhedronPerSolid_3D::StdMeshers_PolyhedronPerSolid_3D(int hypId,
|
|
SMESH_Gen* gen)
|
|
:SMESH_3D_Algo(hypId, gen),
|
|
myEdgeMesher( new _EdgeMesher( gen->GetANewId(), gen )),
|
|
myFaceMesher( new StdMeshers_PolygonPerFace_2D( gen->GetANewId(), gen ))
|
|
{
|
|
_name = "PolyhedronPerSolid_3D";
|
|
_requireDiscreteBoundary = false;
|
|
_supportSubmeshes = true;
|
|
_compatibleHypothesis.push_back("ViscousLayers");
|
|
_neededLowerHyps[0] = _neededLowerHyps[1] = _neededLowerHyps[2] = true;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ~StdMeshers_PolyhedronPerSolid_3D
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
StdMeshers_PolyhedronPerSolid_3D::~StdMeshers_PolyhedronPerSolid_3D()
|
|
{
|
|
delete myEdgeMesher;
|
|
delete myFaceMesher;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : CheckHypothesis
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
bool StdMeshers_PolyhedronPerSolid_3D::CheckHypothesis(SMESH_Mesh& theMesh,
|
|
const TopoDS_Shape& theShape,
|
|
Hypothesis_Status& theStatus)
|
|
{
|
|
myViscousLayersHyp = NULL;
|
|
|
|
const std::list<const SMESHDS_Hypothesis*>& hyps =
|
|
GetUsedHypothesis( theMesh, theShape, /*ignoreAuxiliary=*/false);
|
|
std::list <const SMESHDS_Hypothesis* >::const_iterator h = hyps.begin();
|
|
if ( h == hyps.end())
|
|
{
|
|
theStatus = SMESH_Hypothesis::HYP_OK;
|
|
return true;
|
|
}
|
|
|
|
// only StdMeshers_ViscousLayers can be used
|
|
theStatus = HYP_OK;
|
|
for ( ; h != hyps.end(); ++h )
|
|
{
|
|
if ( !(myViscousLayersHyp = dynamic_cast< const StdMeshers_ViscousLayers*> ( *h )))
|
|
break;
|
|
}
|
|
if ( !myViscousLayersHyp )
|
|
theStatus = HYP_INCOMPATIBLE;
|
|
else
|
|
error( myViscousLayersHyp->CheckHypothesis( theMesh, theShape, theStatus ));
|
|
|
|
return theStatus == HYP_OK;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Compute
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
bool StdMeshers_PolyhedronPerSolid_3D::Compute(SMESH_Mesh& theMesh,
|
|
const TopoDS_Shape& theShape)
|
|
{
|
|
const SMDS_MeshElement* newVolume = 0;
|
|
|
|
SMESH_subMesh* sm = theMesh.GetSubMesh( theShape );
|
|
SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true,
|
|
/*complexFirst=*/false);
|
|
while ( smIt->more() )
|
|
{
|
|
sm = smIt->next();
|
|
if ( !sm->IsEmpty() )
|
|
continue;
|
|
|
|
const TopoDS_Shape & shape = sm->GetSubShape();
|
|
switch ( shape.ShapeType() )
|
|
{
|
|
case TopAbs_VERTEX:
|
|
sm->ComputeStateEngine( SMESH_subMesh::COMPUTE );
|
|
break;
|
|
|
|
case TopAbs_EDGE:
|
|
sm->ComputeStateEngine( SMESH_subMesh::COMPUTE );
|
|
if ( sm->IsEmpty() )
|
|
myEdgeMesher->Compute( theMesh, shape );
|
|
break;
|
|
|
|
case TopAbs_FACE:
|
|
sm->ComputeStateEngine( SMESH_subMesh::COMPUTE );
|
|
if ( sm->IsEmpty() && !myFaceMesher->Compute( theMesh, shape ))
|
|
{
|
|
sm->GetComputeError() = myFaceMesher->GetComputeError();
|
|
sm->GetComputeError()->myAlgo = myFaceMesher;
|
|
return false;
|
|
}
|
|
break;
|
|
|
|
case TopAbs_SOLID:
|
|
{
|
|
SMESH_MesherHelper helper( theMesh );
|
|
helper.SetElementsOnShape( true );
|
|
_quadraticMesh = helper.IsQuadraticSubMesh( shape );
|
|
|
|
SMESH_ProxyMesh::Ptr proxymesh( new SMESH_ProxyMesh( theMesh ));
|
|
if ( myViscousLayersHyp )
|
|
{
|
|
proxymesh = myViscousLayersHyp->Compute( theMesh, theShape );
|
|
if ( !proxymesh )
|
|
return false;
|
|
}
|
|
|
|
std::vector< const SMDS_MeshElement* > faces;
|
|
faces.reserve( 20 );
|
|
|
|
for ( TopExp_Explorer faceEx( shape, TopAbs_FACE ); faceEx.More(); faceEx.Next() )
|
|
{
|
|
const SMESHDS_SubMesh* smDS = proxymesh->GetSubMesh( faceEx.Current() );
|
|
for ( SMDS_ElemIteratorPtr faceIt = smDS->GetElements(); faceIt->more(); )
|
|
faces.push_back( faceIt->next() );
|
|
}
|
|
|
|
bool useMediumNodes = false;
|
|
if ( !_quadraticMesh && theMesh.GetMeshDS()->GetMeshInfo().NbFaces( ORDER_QUADRATIC ))
|
|
for ( size_t i = 0; i < faces.size() && !useMediumNodes ; ++i )
|
|
useMediumNodes = faces[ i ]->IsQuadratic();
|
|
|
|
std::vector< int > quantities( faces.size() );
|
|
std::set< const SMDS_MeshNode* > nodes;
|
|
for ( size_t i = 0; i < faces.size(); ++i )
|
|
{
|
|
quantities[ i ] = useMediumNodes ? faces[ i ]->NbNodes() : faces[ i ]->NbCornerNodes();
|
|
for ( int iN = 0; iN < quantities[ i ]; ++iN )
|
|
nodes.insert( faces[ i ]->GetNode( iN ));
|
|
}
|
|
|
|
const size_t nbNodes = nodes.size(), nbFaces = faces.size();
|
|
if ( nbNodes == 8 && nbFaces == 6 ) newVolume = addHexa ( faces, quantities, helper );
|
|
else if ( nbNodes == 4 && nbFaces == 4 ) newVolume = addTetra ( faces, quantities, helper );
|
|
else if ( nbNodes == 6 && nbFaces == 5 ) newVolume = addPenta ( faces, quantities, helper );
|
|
else if ( nbNodes == 5 && nbFaces == 5 ) newVolume = addPyra ( faces, quantities, helper );
|
|
else if ( nbNodes == 12 && nbFaces == 8 ) newVolume = addHPrism( faces, quantities, helper );
|
|
if ( !newVolume )
|
|
newVolume = addPoly ( faces, quantities, helper );
|
|
|
|
if ( newVolume )
|
|
{
|
|
SMESH::Controls::BadOrientedVolume checker;
|
|
checker.SetMesh( theMesh.GetMeshDS() );
|
|
if ( checker.IsSatisfy( newVolume->GetID() ))
|
|
{
|
|
SMESH_MeshEditor editor( &theMesh );
|
|
editor.Reorient( newVolume );
|
|
}
|
|
}
|
|
}
|
|
default:;
|
|
|
|
} // switch ( shape.ShapeType() )
|
|
} // loop on sub-meshes
|
|
|
|
return newVolume;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Evaluate
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
bool StdMeshers_PolyhedronPerSolid_3D::Evaluate(SMESH_Mesh& theMesh,
|
|
const TopoDS_Shape& theShape,
|
|
MapShapeNbElems& theResMap)
|
|
{
|
|
_quadraticMesh = false;
|
|
|
|
SMESH_subMesh* sm = theMesh.GetSubMesh( theShape );
|
|
SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true,
|
|
/*complexFirst=*/false);
|
|
while ( smIt->more() )
|
|
{
|
|
sm = smIt->next();
|
|
|
|
MapShapeNbElems::iterator sm2vec = theResMap.find( sm );
|
|
if ( sm2vec != theResMap.end() && !sm2vec->second.empty() )
|
|
continue;
|
|
|
|
const TopoDS_Shape & shape = sm->GetSubShape();
|
|
switch ( shape.ShapeType() )
|
|
{
|
|
case TopAbs_EDGE:
|
|
myEdgeMesher->Evaluate( theMesh, shape, theResMap );
|
|
break;
|
|
|
|
case TopAbs_FACE:
|
|
{
|
|
myFaceMesher->Evaluate( theMesh, shape, theResMap );
|
|
std::vector<smIdType> & quantities = theResMap[ sm ];
|
|
_quadraticMesh = ( !quantities.empty() &&
|
|
( quantities[ SMDSEntity_Quad_Triangle ] +
|
|
quantities[ SMDSEntity_Quad_Quadrangle ] +
|
|
quantities[ SMDSEntity_Quad_Polygon ]));
|
|
break;
|
|
}
|
|
|
|
case TopAbs_SOLID:
|
|
{
|
|
std::vector<smIdType> & quantities = theResMap[ sm ];
|
|
quantities.resize( SMDSEntity_Last, 0 );
|
|
|
|
SMESH_MesherHelper helper( theMesh );
|
|
const int nbNodes = helper.Count( shape, TopAbs_VERTEX, /*ignoreSame=*/true );
|
|
const int nbFaces = helper.Count( shape, TopAbs_FACE, /*ignoreSame=*/false );
|
|
|
|
if ( nbNodes == 8 && nbFaces == 6 )
|
|
quantities[ _quadraticMesh ? SMDSEntity_Quad_Hexa : SMDSEntity_Hexa ] = 1;
|
|
else if ( nbNodes == 4 && nbFaces == 4 )
|
|
quantities[ _quadraticMesh ? SMDSEntity_Quad_Tetra : SMDSEntity_Tetra ] = 1;
|
|
else if ( nbNodes == 6 && nbFaces == 5 )
|
|
quantities[ _quadraticMesh ? SMDSEntity_Quad_Penta : SMDSEntity_Penta ] = 1;
|
|
else if ( nbNodes == 5 && nbFaces == 5 )
|
|
quantities[ _quadraticMesh ? SMDSEntity_Quad_Pyramid : SMDSEntity_Pyramid ] = 1;
|
|
else if ( nbNodes == 12 && nbFaces == 8 )
|
|
quantities[ /*_quadraticMesh ? SMDSEntity_Quad_Pyramid :*/ SMDSEntity_Hexagonal_Prism ] = 1;
|
|
else
|
|
quantities[ /*_quadraticMesh ? SMDSEntity_Quad_Polyhedra : */SMDSEntity_Polyhedra ] = 1;
|
|
|
|
return true;
|
|
}
|
|
default:;
|
|
|
|
} // switch ( shape.ShapeType() )
|
|
} // loop on sub-meshes
|
|
|
|
return false;
|
|
}
|