smesh/src/StdMeshers/StdMeshers_Projection_3D.cxx

580 lines
21 KiB
C++
Raw Normal View History

2015-02-13 13:38:35 +05:00
// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
2009-02-17 10:27:49 +05:00
//
2012-08-09 16:03:55 +06:00
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
2009-02-17 10:27:49 +05:00
//
2012-08-09 16:03:55 +06:00
// 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
2014-02-20 18:25:37 +06:00
// version 2.1 of the License, or (at your option) any later version.
//
2012-08-09 16:03:55 +06:00
// 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.
//
2012-08-09 16:03:55 +06:00
// 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
//
2012-08-09 16:03:55 +06:00
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
2012-08-09 16:03:55 +06:00
2009-02-17 10:27:49 +05:00
// SMESH SMESH : implementaion of SMESH idl descriptions
// File : StdMeshers_Projection_3D.cxx
// Module : SMESH
// Created : Fri Oct 20 11:37:07 2006
// Author : Edward AGAPOV (eap)
2009-02-17 10:27:49 +05:00
//
#include "StdMeshers_Projection_3D.hxx"
#include "StdMeshers_ProjectionSource3D.hxx"
#include "StdMeshers_ProjectionUtils.hxx"
2012-08-09 16:03:55 +06:00
#include "SMDS_PolyhedralVolumeOfNodes.hxx"
#include "SMDS_VolumeTool.hxx"
#include "SMESHDS_Hypothesis.hxx"
#include "SMESHDS_SubMesh.hxx"
#include "SMESH_Block.hxx"
2012-08-09 16:03:55 +06:00
#include "SMESH_Comment.hxx"
#include "SMESH_Gen.hxx"
#include "SMESH_Mesh.hxx"
2012-08-09 16:03:55 +06:00
#include "SMESH_MesherHelper.hxx"
#include "SMESH_Pattern.hxx"
#include "SMESH_subMesh.hxx"
#include "SMESH_subMeshEventListener.hxx"
#include "utilities.h"
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#define RETURN_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); return false; }
#define gpXYZ(n) gp_XYZ(n->X(),n->Y(),n->Z())
#define SHOWYXZ(msg, xyz) // {\
// gp_Pnt p (xyz); \
// cout << msg << " ("<< p.X() << "; " <<p.Y() << "; " <<p.Z() << ") " <<endl;\
// }
2013-02-28 21:07:35 +06:00
namespace TAssocTool = StdMeshers_ProjectionUtils;
//=======================================================================
//function : StdMeshers_Projection_3D
//purpose :
//=======================================================================
StdMeshers_Projection_3D::StdMeshers_Projection_3D(int hypId, int studyId, SMESH_Gen* gen)
:SMESH_3D_Algo(hypId, studyId, gen)
{
_name = "Projection_3D";
2012-08-09 16:03:55 +06:00
_shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit per shape type
_compatibleHypothesis.push_back("ProjectionSource3D");
_sourceHypo = 0;
}
//================================================================================
/*!
* \brief Destructor
*/
//================================================================================
StdMeshers_Projection_3D::~StdMeshers_Projection_3D()
{}
//=======================================================================
//function : CheckHypothesis
//purpose :
//=======================================================================
bool StdMeshers_Projection_3D::CheckHypothesis(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape,
SMESH_Hypothesis::Hypothesis_Status& aStatus)
{
// check aShape that must be a 6 faces block
/* PAL16229
if ( TAssocTool::Count( aShape, TopAbs_SHELL, 1 ) != 1 ||
TAssocTool::Count( aShape, TopAbs_FACE , 1 ) != 6 ||
TAssocTool::Count( aShape, TopAbs_EDGE , 1 ) != 12 ||
TAssocTool::Count( aShape, TopAbs_WIRE , 1 ) != 6 )
{
aStatus = HYP_BAD_GEOMETRY;
return false;
}
*/
list <const SMESHDS_Hypothesis * >::const_iterator itl;
const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
if ( hyps.size() == 0 )
{
aStatus = SMESH_Hypothesis::HYP_MISSING;
return false; // can't work with no hypothesis
}
if ( hyps.size() > 1 )
{
aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST;
return false;
}
const SMESHDS_Hypothesis *theHyp = hyps.front();
string hypName = theHyp->GetName();
aStatus = SMESH_Hypothesis::HYP_OK;
if (hypName == "ProjectionSource3D")
{
_sourceHypo = static_cast<const StdMeshers_ProjectionSource3D *>(theHyp);
// Check hypo parameters
SMESH_Mesh* srcMesh = _sourceHypo->GetSourceMesh();
SMESH_Mesh* tgtMesh = & aMesh;
if ( !srcMesh )
srcMesh = tgtMesh;
// check vertices
if ( _sourceHypo->HasVertexAssociation() )
{
// source vertices
TopoDS_Shape edge = TAssocTool::GetEdgeByVertices
( srcMesh, _sourceHypo->GetSourceVertex(1), _sourceHypo->GetSourceVertex(2) );
if ( edge.IsNull() ||
2012-08-09 16:03:55 +06:00
!SMESH_MesherHelper::IsSubShape( edge, srcMesh ) ||
!SMESH_MesherHelper::IsSubShape( edge, _sourceHypo->GetSource3DShape() ))
{
SCRUTE((edge.IsNull()));
2012-08-09 16:03:55 +06:00
SCRUTE((SMESH_MesherHelper::IsSubShape( edge, srcMesh )));
SCRUTE((SMESH_MesherHelper::IsSubShape( edge, _sourceHypo->GetSource3DShape() )));
aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
}
else
{
// target vertices
edge = TAssocTool::GetEdgeByVertices
( tgtMesh, _sourceHypo->GetTargetVertex(1), _sourceHypo->GetTargetVertex(2) );
if ( edge.IsNull() ||
2012-08-09 16:03:55 +06:00
!SMESH_MesherHelper::IsSubShape( edge, tgtMesh ) ||
!SMESH_MesherHelper::IsSubShape( edge, aShape ))
{
SCRUTE((edge.IsNull()));
2012-08-09 16:03:55 +06:00
SCRUTE((SMESH_MesherHelper::IsSubShape( edge, tgtMesh )));
SCRUTE((SMESH_MesherHelper::IsSubShape( edge, aShape )));
aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
}
}
}
// check a source shape
2012-08-09 16:03:55 +06:00
if ( !SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSource3DShape(), srcMesh ) ||
( srcMesh == tgtMesh && aShape == _sourceHypo->GetSource3DShape()))
{
2012-08-09 16:03:55 +06:00
SCRUTE((SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSource3DShape(), srcMesh)));
SCRUTE((srcMesh == tgtMesh));
SCRUTE((aShape == _sourceHypo->GetSource3DShape()));
aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
}
}
else
{
aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
}
return ( aStatus == HYP_OK );
}
//=======================================================================
//function : Compute
//purpose :
//=======================================================================
bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
{
if ( !_sourceHypo )
return false;
SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh();
SMESH_Mesh * tgtMesh = & aMesh;
if ( !srcMesh )
srcMesh = tgtMesh;
SMESHDS_Mesh * srcMeshDS = srcMesh->GetMeshDS();
SMESHDS_Mesh * tgtMeshDS = tgtMesh->GetMeshDS();
// get shell from shape3D
TopoDS_Shell srcShell, tgtShell;
TopExp_Explorer exp( _sourceHypo->GetSource3DShape(), TopAbs_SHELL );
int nbShell;
for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell )
srcShell = TopoDS::Shell( exp.Current() );
if ( nbShell != 1 )
return error(COMPERR_BAD_SHAPE,
SMESH_Comment("Source shape must have 1 shell but not ") << nbShell);
exp.Init( aShape, TopAbs_SHELL );
for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell )
tgtShell = TopoDS::Shell( exp.Current() );
if ( nbShell != 1 )
return error(COMPERR_BAD_SHAPE,
SMESH_Comment("Target shape must have 1 shell but not ") << nbShell);
// Check that shapes are blocks
2013-02-12 20:37:44 +06:00
if ( SMESH_MesherHelper::Count( tgtShell, TopAbs_FACE , 1 ) != 6 ||
SMESH_MesherHelper::Count( tgtShell, TopAbs_EDGE , 1 ) != 12 ||
SMESH_MesherHelper::Count( tgtShell, TopAbs_WIRE , 1 ) != 6 )
return error(COMPERR_BAD_SHAPE, "Target shape is not a block");
2013-02-12 20:37:44 +06:00
if ( SMESH_MesherHelper::Count( srcShell, TopAbs_FACE , 1 ) != 6 ||
SMESH_MesherHelper::Count( srcShell, TopAbs_EDGE , 1 ) != 12 ||
SMESH_MesherHelper::Count( srcShell, TopAbs_WIRE , 1 ) != 6 )
return error(COMPERR_BAD_SHAPE, "Source shape is not a block");
// Assure that mesh on a source shape is computed
SMESH_subMesh* srcSubMesh = srcMesh->GetSubMesh( _sourceHypo->GetSource3DShape() );
//SMESH_subMesh* tgtSubMesh = tgtMesh->GetSubMesh( aShape );
2013-02-28 21:07:35 +06:00
string srcMeshError;
if ( tgtMesh == srcMesh && !aShape.IsSame( _sourceHypo->GetSource3DShape() )) {
if ( !TAssocTool::MakeComputed( srcSubMesh ))
2013-02-28 21:07:35 +06:00
srcMeshError = TAssocTool::SourceNotComputedError( srcSubMesh, this );
}
else {
if ( !srcSubMesh->IsMeshComputed() )
2013-02-28 21:07:35 +06:00
srcMeshError = TAssocTool::SourceNotComputedError();
}
// Find 2 pairs of corresponding vertices
TopoDS_Vertex tgtV000, tgtV100, srcV000, srcV100;
TAssocTool::TShapeShapeMap shape2ShapeMap;
if ( _sourceHypo->HasVertexAssociation() )
{
tgtV000 = _sourceHypo->GetTargetVertex(1);
tgtV100 = _sourceHypo->GetTargetVertex(2);
srcV000 = _sourceHypo->GetSourceVertex(1);
srcV100 = _sourceHypo->GetSourceVertex(2);
}
else
{
if ( !TAssocTool::FindSubShapeAssociation( tgtShell, tgtMesh, srcShell, srcMesh,
shape2ShapeMap) )
return error(COMPERR_BAD_SHAPE,"Topology of source and target shapes seems different" );
exp.Init( tgtShell, TopAbs_EDGE );
TopExp::Vertices( TopoDS::Edge( exp.Current() ), tgtV000, tgtV100 );
if ( !shape2ShapeMap.IsBound( tgtV000 ) || !shape2ShapeMap.IsBound( tgtV100 ))
2012-08-09 16:03:55 +06:00
return error("Association of sub-shapes failed" );
srcV000 = TopoDS::Vertex( shape2ShapeMap( tgtV000 ));
srcV100 = TopoDS::Vertex( shape2ShapeMap( tgtV100 ));
2012-08-09 16:03:55 +06:00
if ( !SMESH_MesherHelper::IsSubShape( srcV000, srcShell ) ||
!SMESH_MesherHelper::IsSubShape( srcV100, srcShell ))
return error("Incorrect association of sub-shapes" );
}
// Load 2 SMESH_Block's with src and tgt shells
SMESH_Block srcBlock, tgtBlock;
TopTools_IndexedMapOfOrientedShape scrShapes, tgtShapes;
if ( !tgtBlock.LoadBlockShapes( tgtShell, tgtV000, tgtV100, tgtShapes ))
2012-08-09 16:03:55 +06:00
return error(COMPERR_BAD_SHAPE, "Can't detect block sub-shapes. Not a block?");
if ( !srcBlock.LoadBlockShapes( srcShell, srcV000, srcV100, scrShapes ))
2012-08-09 16:03:55 +06:00
return error(COMPERR_BAD_SHAPE, "Can't detect block sub-shapes. Not a block?");
// Find matching nodes of src and tgt shells
TNodeNodeMap src2tgtNodeMap;
for ( int fId = SMESH_Block::ID_FirstF; fId < SMESH_Block::ID_Shell; ++fId )
{
2012-08-09 16:03:55 +06:00
// Corresponding sub-shapes
TopoDS_Face srcFace = TopoDS::Face( scrShapes( fId ));
TopoDS_Face tgtFace = TopoDS::Face( tgtShapes( fId ));
2012-08-09 16:03:55 +06:00
if ( _sourceHypo->HasVertexAssociation() ) { // associate face sub-shapes
shape2ShapeMap.Clear();
vector< int > edgeIdVec;
SMESH_Block::GetFaceEdgesIDs( fId, edgeIdVec );
for ( int i = 0; i < edgeIdVec.size(); ++i ) {
int eID = edgeIdVec[ i ];
2012-10-08 17:56:59 +06:00
shape2ShapeMap.Bind( scrShapes( eID ), tgtShapes( eID ));
if ( i < 2 ) {
vector< int > vertexIdVec;
SMESH_Block::GetEdgeVertexIDs( eID, vertexIdVec );
2012-10-08 17:56:59 +06:00
shape2ShapeMap.Bind( scrShapes( vertexIdVec[0]), tgtShapes( vertexIdVec[0]) );
shape2ShapeMap.Bind( scrShapes( vertexIdVec[1]), tgtShapes( vertexIdVec[1]) );
}
}
}
// Find matching nodes of tgt and src faces
TAssocTool::TNodeNodeMap faceMatchingNodes;
if ( ! TAssocTool::FindMatchingNodesOnFaces( srcFace, srcMesh, tgtFace, tgtMesh,
shape2ShapeMap, faceMatchingNodes ))
2012-08-09 16:03:55 +06:00
return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Mesh on faces #")
<< srcMeshDS->ShapeToIndex( srcFace ) << " and "
<< tgtMeshDS->ShapeToIndex( tgtFace ) << " seems different" );
// put found matching nodes of 2 faces to the global map
src2tgtNodeMap.insert( faceMatchingNodes.begin(), faceMatchingNodes.end() );
}
// ------------------
// Make mesh
// ------------------
SMDS_VolumeTool volTool;
SMESH_MesherHelper helper( *tgtMesh );
helper.IsQuadraticSubMesh( aShape );
SMESHDS_SubMesh* srcSMDS = srcSubMesh->GetSubMeshDS();
SMDS_ElemIteratorPtr volIt = srcSMDS->GetElements();
while ( volIt->more() ) // loop on source volumes
{
const SMDS_MeshElement* srcVol = volIt->next();
if ( !srcVol || srcVol->GetType() != SMDSAbs_Volume )
continue;
int nbNodes = srcVol->NbNodes();
SMDS_VolumeTool::VolumeType volType = volTool.GetType( nbNodes );
if ( srcVol->IsQuadratic() )
nbNodes = volTool.NbCornerNodes( volType );
// Find or create a new tgt node for each node of a src volume
vector< const SMDS_MeshNode* > nodes( nbNodes );
for ( int i = 0; i < nbNodes; ++i )
{
const SMDS_MeshNode* srcNode = srcVol->GetNode( i );
const SMDS_MeshNode* tgtNode = 0;
TNodeNodeMap::iterator sN_tN = src2tgtNodeMap.find( srcNode );
if ( sN_tN != src2tgtNodeMap.end() ) // found
{
tgtNode = sN_tN->second;
}
else // Create a new tgt node
{
// compute normalized parameters of source node in srcBlock
gp_Pnt srcCoord = gpXYZ( srcNode );
gp_XYZ srcParam;
if ( !srcBlock.ComputeParameters( srcCoord, srcParam ))
return error(SMESH_Comment("Can't compute normalized parameters ")
<< "for source node " << srcNode->GetID());
// compute coordinates of target node by srcParam
gp_XYZ tgtXYZ;
if ( !tgtBlock.ShellPoint( srcParam, tgtXYZ ))
return error("Can't compute coordinates by normalized parameters");
// add node
SMDS_MeshNode* newNode = tgtMeshDS->AddNode( tgtXYZ.X(), tgtXYZ.Y(), tgtXYZ.Z() );
tgtMeshDS->SetNodeInVolume( newNode, helper.GetSubShapeID() );
tgtNode = newNode;
src2tgtNodeMap.insert( make_pair( srcNode, tgtNode ));
}
nodes[ i ] = tgtNode;
}
// Create a new volume
SMDS_MeshVolume * tgtVol = 0;
int id = 0, force3d = false;
switch ( volType ) {
case SMDS_VolumeTool::TETRA :
case SMDS_VolumeTool::QUAD_TETRA:
tgtVol = helper.AddVolume( nodes[0],
nodes[1],
nodes[2],
nodes[3], id, force3d); break;
case SMDS_VolumeTool::PYRAM :
case SMDS_VolumeTool::QUAD_PYRAM:
tgtVol = helper.AddVolume( nodes[0],
nodes[1],
nodes[2],
nodes[3],
nodes[4], id, force3d); break;
case SMDS_VolumeTool::PENTA :
case SMDS_VolumeTool::QUAD_PENTA:
tgtVol = helper.AddVolume( nodes[0],
nodes[1],
nodes[2],
nodes[3],
nodes[4],
nodes[5], id, force3d); break;
case SMDS_VolumeTool::HEXA :
case SMDS_VolumeTool::QUAD_HEXA :
tgtVol = helper.AddVolume( nodes[0],
nodes[1],
nodes[2],
nodes[3],
nodes[4],
nodes[5],
nodes[6],
nodes[7], id, force3d); break;
default: // polyhedron
2012-08-09 16:03:55 +06:00
const SMDS_VtkVolume * poly =
dynamic_cast<const SMDS_VtkVolume*>( srcVol );
if ( !poly )
RETURN_BAD_RESULT("Unexpected volume type");
2012-08-09 16:03:55 +06:00
if ( !poly->IsPoly())
RETURN_BAD_RESULT("Unexpected volume type");
tgtVol = tgtMeshDS->AddPolyhedralVolume( nodes, poly->GetQuantities() );
}
if ( tgtVol ) {
tgtMeshDS->SetMeshElementOnShape( tgtVol, helper.GetSubShapeID() );
}
} // loop on volumes of src shell
return true;
}
2012-08-09 16:03:55 +06:00
//=======================================================================
//function : Evaluate
//purpose :
//=======================================================================
bool StdMeshers_Projection_3D::Evaluate(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape,
MapShapeNbElems& aResMap)
{
if ( !_sourceHypo )
return false;
SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh();
SMESH_Mesh * tgtMesh = & aMesh;
if ( !srcMesh )
srcMesh = tgtMesh;
// get shell from shape3D
TopoDS_Shell srcShell, tgtShell;
TopExp_Explorer exp( _sourceHypo->GetSource3DShape(), TopAbs_SHELL );
int nbShell;
for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell )
srcShell = TopoDS::Shell( exp.Current() );
if ( nbShell != 1 )
return error(COMPERR_BAD_SHAPE,
SMESH_Comment("Source shape must have 1 shell but not ") << nbShell);
exp.Init( aShape, TopAbs_SHELL );
for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell )
tgtShell = TopoDS::Shell( exp.Current() );
if ( nbShell != 1 )
return error(COMPERR_BAD_SHAPE,
SMESH_Comment("Target shape must have 1 shell but not ") << nbShell);
// Check that shapes are blocks
2013-02-12 20:37:44 +06:00
if ( SMESH_MesherHelper::Count( tgtShell, TopAbs_FACE , 1 ) != 6 ||
SMESH_MesherHelper::Count( tgtShell, TopAbs_EDGE , 1 ) != 12 ||
SMESH_MesherHelper::Count( tgtShell, TopAbs_WIRE , 1 ) != 6 )
2012-08-09 16:03:55 +06:00
return error(COMPERR_BAD_SHAPE, "Target shape is not a block");
2013-02-12 20:37:44 +06:00
if ( SMESH_MesherHelper::Count( srcShell, TopAbs_FACE , 1 ) != 6 ||
SMESH_MesherHelper::Count( srcShell, TopAbs_EDGE , 1 ) != 12 ||
SMESH_MesherHelper::Count( srcShell, TopAbs_WIRE , 1 ) != 6 )
2012-08-09 16:03:55 +06:00
return error(COMPERR_BAD_SHAPE, "Source shape is not a block");
// Assure that mesh on a source shape is computed
SMESH_subMesh* srcSubMesh = srcMesh->GetSubMesh( _sourceHypo->GetSource3DShape() );
if ( !srcSubMesh->IsMeshComputed() )
return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
std::vector<int> aVec(SMDSEntity_Last);
for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i] = 0;
aVec[SMDSEntity_Node] = srcSubMesh->GetSubMeshDS()->NbNodes();
//bool quadratic = false;
SMDS_ElemIteratorPtr elemIt = srcSubMesh->GetSubMeshDS()->GetElements();
while ( elemIt->more() ) {
const SMDS_MeshElement* E = elemIt->next();
if( E->NbNodes()==4 ) {
aVec[SMDSEntity_Tetra]++;
}
else if( E->NbNodes()==5 ) {
aVec[SMDSEntity_Pyramid]++;
}
else if( E->NbNodes()==6 ) {
aVec[SMDSEntity_Penta]++;
}
else if( E->NbNodes()==8 ) {
aVec[SMDSEntity_Hexa]++;
}
else if( E->NbNodes()==10 && E->IsQuadratic() ) {
aVec[SMDSEntity_Quad_Tetra]++;
}
else if( E->NbNodes()==13 && E->IsQuadratic() ) {
aVec[SMDSEntity_Quad_Pyramid]++;
}
else if( E->NbNodes()==15 && E->IsQuadratic() ) {
aVec[SMDSEntity_Quad_Penta]++;
}
else if( E->NbNodes()==20 && E->IsQuadratic() ) {
aVec[SMDSEntity_Quad_Hexa]++;
}
else {
aVec[SMDSEntity_Polyhedra]++;
}
}
SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
aResMap.insert(std::make_pair(sm,aVec));
return true;
}
//=============================================================================
/*!
* \brief Sets a default event listener to submesh of the source shape
* \param subMesh - submesh where algo is set
*
* This method is called when a submesh gets HYP_OK algo_state.
* After being set, event listener is notified on each event of a submesh.
* Arranges that CLEAN event is translated from source submesh to
* the submesh
*/
//=============================================================================
void StdMeshers_Projection_3D::SetEventListener(SMESH_subMesh* subMesh)
{
TAssocTool::SetEventListener( subMesh,
_sourceHypo->GetSource3DShape(),
_sourceHypo->GetSourceMesh() );
}
//================================================================================
/*!
* \brief Return true if the algorithm can mesh this shape
* \param [in] aShape - shape to check
* \param [in] toCheckAll - if true, this check returns OK if all shapes are OK,
* else, returns OK if at least one shape is OK
*/
//================================================================================
bool StdMeshers_Projection_3D::IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll)
{
TopExp_Explorer exp0( aShape, TopAbs_SOLID );
if ( !exp0.More() ) return false;
TopTools_IndexedMapOfOrientedShape blockShapes;
TopoDS_Vertex v;
TopoDS_Shell shell;
for ( ; exp0.More(); exp0.Next() )
{
int nbFoundShells = 0;
TopExp_Explorer exp1( exp0.Current(), TopAbs_SHELL );
for ( ; exp1.More(); exp1.Next(), ++nbFoundShells )
{
shell = TopoDS::Shell( exp1.Current() );
if ( nbFoundShells == 2 ) break;
}
if ( nbFoundShells != 1 ) {
if ( toCheckAll ) return false;
continue;
}
bool isBlock = SMESH_Block::FindBlockShapes( shell, v, v, blockShapes );
if ( toCheckAll && !isBlock ) return false;
if ( !toCheckAll && isBlock ) return true;
}
return toCheckAll;
}