bos #20282 EDF 22320 - general compute fails

This commit is contained in:
eap 2020-11-12 23:06:06 +03:00
parent c835e6ad6d
commit fdab1d32d5
8 changed files with 183 additions and 75 deletions

View File

@ -63,6 +63,43 @@ using namespace std;
#define env_sep ':' #define env_sep ':'
#endif #endif
namespace
{
// a structure used to nullify SMESH_Gen field of SMESH_Hypothesis,
// which is needed for SMESH_Hypothesis not deleted before ~SMESH_Gen()
struct _Hyp : public SMESH_Hypothesis
{
void NullifyGen()
{
_gen = 0;
}
};
//================================================================================
/*!
* \brief Fill a map of shapes with all sub-shape of a sub-mesh
*/
//================================================================================
TopTools_IndexedMapOfShape * fillAllowed( SMESH_subMesh* sm,
const bool toFill,
TopTools_IndexedMapOfShape * allowedSub )
{
if ( !toFill || !allowedSub )
{
return nullptr;
}
if ( allowedSub->IsEmpty() )
{
allowedSub->ReSize( sm->DependsOn().size() + 1 );
allowedSub->Add( sm->GetSubShape() );
for ( const auto & key_sm : sm->DependsOn() )
allowedSub->Add( key_sm.second->GetSubShape() );
}
return allowedSub;
}
}
//============================================================================= //=============================================================================
/*! /*!
* Constructor * Constructor
@ -79,19 +116,6 @@ SMESH_Gen::SMESH_Gen()
_compute_canceled = false; _compute_canceled = false;
} }
namespace
{
// a structure used to nullify SMESH_Gen field of SMESH_Hypothesis,
// which is needed for SMESH_Hypothesis not deleted before ~SMESH_Gen()
struct _Hyp : public SMESH_Hypothesis
{
void NullifyGen()
{
_gen = 0;
}
};
}
//============================================================================= //=============================================================================
/*! /*!
* Destructor * Destructor
@ -138,11 +162,12 @@ SMESH_Mesh* SMESH_Gen::CreateMesh(bool theIsEmbeddedMode)
*/ */
//============================================================================= //=============================================================================
bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
const TopoDS_Shape & aShape, const TopoDS_Shape & aShape,
const int aFlags /*= COMPACT_MESH*/, const int aFlags /*= COMPACT_MESH*/,
const ::MeshDimension aDim /*=::MeshDim_3D*/, const ::MeshDimension aDim /*=::MeshDim_3D*/,
TSetOfInt* aShapesId /*=0*/) TSetOfInt* aShapesId /*=0*/,
TopTools_IndexedMapOfShape* anAllowedSubShapes/*=0*/)
{ {
MEMOSTAT; MEMOSTAT;
@ -152,7 +177,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
bool ret = true; bool ret = true;
SMESH_subMesh *sm = aMesh.GetSubMesh(aShape); SMESH_subMesh *sm, *shapeSM = aMesh.GetSubMesh(aShape);
const bool includeSelf = true; const bool includeSelf = true;
const bool complexShapeFirst = true; const bool complexShapeFirst = true;
@ -168,13 +193,17 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
if ( !aMesh.HasShapeToMesh() ) if ( !aMesh.HasShapeToMesh() )
computeEvent = SMESH_subMesh::COMPUTE_NOGEOM; // if several algos and no geometry computeEvent = SMESH_subMesh::COMPUTE_NOGEOM; // if several algos and no geometry
TopTools_IndexedMapOfShape *allowedSubShapes = anAllowedSubShapes, allowedSub;
if ( aShapeOnly && !allowedSubShapes )
allowedSubShapes = &allowedSub;
if ( anUpward ) // is called from the below code in this method if ( anUpward ) // is called from the below code in this method
{ {
// =============================================== // ===============================================
// Mesh all the sub-shapes starting from vertices // Mesh all the sub-shapes starting from vertices
// =============================================== // ===============================================
smIt = sm->getDependsOnIterator(includeSelf, !complexShapeFirst); smIt = shapeSM->getDependsOnIterator(includeSelf, !complexShapeFirst);
while ( smIt->more() ) while ( smIt->more() )
{ {
SMESH_subMesh* smToCompute = smIt->next(); SMESH_subMesh* smToCompute = smIt->next();
@ -198,9 +227,11 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
{ {
if (_compute_canceled) if (_compute_canceled)
return false; return false;
smToCompute->SetAllowedSubShapes( fillAllowed( shapeSM, aShapeOnly, allowedSubShapes ));
setCurrentSubMesh( smToCompute ); setCurrentSubMesh( smToCompute );
smToCompute->ComputeStateEngine( computeEvent ); smToCompute->ComputeStateEngine( computeEvent );
setCurrentSubMesh( NULL ); setCurrentSubMesh( nullptr );
smToCompute->SetAllowedSubShapes( nullptr );
} }
// we check all the sub-meshes here and detect if any of them failed to compute // we check all the sub-meshes here and detect if any of them failed to compute
@ -233,7 +264,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
TopoDS_Shape algoShape; TopoDS_Shape algoShape;
int prevShapeDim = -1, aShapeDim; int prevShapeDim = -1, aShapeDim;
smIt = sm->getDependsOnIterator(includeSelf, complexShapeFirst); smIt = shapeSM->getDependsOnIterator(includeSelf, complexShapeFirst);
while ( smIt->more() ) while ( smIt->more() )
{ {
SMESH_subMesh* smToCompute = smIt->next(); SMESH_subMesh* smToCompute = smIt->next();
@ -285,9 +316,11 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
{ {
if (_compute_canceled) if (_compute_canceled)
return false; return false;
smToCompute->SetAllowedSubShapes( fillAllowed( shapeSM, aShapeOnly, allowedSubShapes ));
setCurrentSubMesh( smToCompute ); setCurrentSubMesh( smToCompute );
smToCompute->ComputeStateEngine( computeEvent ); smToCompute->ComputeStateEngine( computeEvent );
setCurrentSubMesh( NULL ); setCurrentSubMesh( nullptr );
smToCompute->SetAllowedSubShapes( nullptr );
if ( aShapesId ) if ( aShapesId )
aShapesId->insert( smToCompute->GetId() ); aShapesId->insert( smToCompute->GetId() );
} }
@ -335,7 +368,6 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
const TopoDS_Shape& aSubShape = smToCompute->GetSubShape(); const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
const int aShapeDim = GetShapeDim( aSubShape ); const int aShapeDim = GetShapeDim( aSubShape );
//if ( aSubShape.ShapeType() == TopAbs_VERTEX ) continue;
if ( aShapeDim < 1 ) continue; if ( aShapeDim < 1 ) continue;
// check for preview dimension limitations // check for preview dimension limitations
@ -350,11 +382,14 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( smToCompute, filter, true)) if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( smToCompute, filter, true))
{ {
if ( ! subAlgo->NeedDiscreteBoundary() ) continue; if ( ! subAlgo->NeedDiscreteBoundary() ) continue;
TopTools_IndexedMapOfShape* localAllowed = allowedSubShapes;
if ( localAllowed && localAllowed->IsEmpty() )
localAllowed = 0; // prevent fillAllowed() with aSubShape
SMESH_Hypothesis::Hypothesis_Status status; SMESH_Hypothesis::Hypothesis_Status status;
if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status )) if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status ))
// mesh a lower smToCompute starting from vertices // mesh a lower smToCompute starting from vertices
Compute( aMesh, aSubShape, aFlags | SHAPE_ONLY_UPWARD, aDim, aShapesId ); Compute( aMesh, aSubShape, aFlags | SHAPE_ONLY_UPWARD, aDim, aShapesId, localAllowed );
// Compute( aMesh, aSubShape, aShapeOnly, /*anUpward=*/true, aDim, aShapesId );
} }
} }
} }
@ -373,9 +408,11 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
if (_compute_canceled) if (_compute_canceled)
return false; return false;
sm->SetAllowedSubShapes( fillAllowed( shapeSM, aShapeOnly, allowedSubShapes ));
setCurrentSubMesh( sm ); setCurrentSubMesh( sm );
sm->ComputeStateEngine( computeEvent ); sm->ComputeStateEngine( computeEvent );
setCurrentSubMesh( NULL ); setCurrentSubMesh( NULL );
sm->SetAllowedSubShapes( nullptr );
if ( aShapesId ) if ( aShapesId )
aShapesId->insert( sm->GetId() ); aShapesId->insert( sm->GetId() );
} }
@ -385,7 +422,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
// ----------------------------------------------- // -----------------------------------------------
// mesh the rest sub-shapes starting from vertices // mesh the rest sub-shapes starting from vertices
// ----------------------------------------------- // -----------------------------------------------
ret = Compute( aMesh, aShape, aFlags | UPWARD, aDim, aShapesId ); ret = Compute( aMesh, aShape, aFlags | UPWARD, aDim, aShapesId, allowedSubShapes );
} }
MEMOSTAT; MEMOSTAT;
@ -399,7 +436,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
SMESH_MesherHelper aHelper( aMesh ); SMESH_MesherHelper aHelper( aMesh );
if ( aHelper.IsQuadraticMesh() != SMESH_MesherHelper::LINEAR ) if ( aHelper.IsQuadraticMesh() != SMESH_MesherHelper::LINEAR )
{ {
aHelper.FixQuadraticElements( sm->GetComputeError() ); aHelper.FixQuadraticElements( shapeSM->GetComputeError() );
} }
} }

View File

@ -42,6 +42,7 @@
#include <string> #include <string>
#include <TopoDS_Shape.hxx> #include <TopoDS_Shape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
class SMESHDS_Document; class SMESHDS_Document;
class SMESH_Algo; class SMESH_Algo;
@ -83,13 +84,15 @@ public:
* \param aFlags - ComputeFlags. By default compute the whole mesh and compact at the end. * \param aFlags - ComputeFlags. By default compute the whole mesh and compact at the end.
* \param aDim - upper level dimension of the mesh computation (for preview) * \param aDim - upper level dimension of the mesh computation (for preview)
* \param aShapesId - list of shapes with computed mesh entities (elements or nodes) * \param aShapesId - list of shapes with computed mesh entities (elements or nodes)
* \param anAllowedSubShapes - shapes to mesh only. Mesh all if empty or nullptr
* \retval bool - true if none sub-mesh failed to compute * \retval bool - true if none sub-mesh failed to compute
*/ */
bool Compute(::SMESH_Mesh & aMesh, bool Compute(::SMESH_Mesh & aMesh,
const TopoDS_Shape & aShape, const TopoDS_Shape & aShape,
const int aFlags = COMPACT_MESH, const int aFlags = COMPACT_MESH,
const ::MeshDimension aDim=::MeshDim_3D, const ::MeshDimension aDim=::MeshDim_3D,
TSetOfInt* aShapesId=0); TSetOfInt* aShapesId=0,
TopTools_IndexedMapOfShape* anAllowedSubShapes=0);
void PrepareCompute(::SMESH_Mesh & aMesh, void PrepareCompute(::SMESH_Mesh & aMesh,
const TopoDS_Shape & aShape); const TopoDS_Shape & aShape);

View File

@ -156,7 +156,7 @@ void SMESH_HypoFilter::IsMoreLocalThanPredicate::findPreferable()
//======================================================================= //=======================================================================
//function : IsMoreLocalThanPredicate::IsOk //function : IsMoreLocalThanPredicate::IsOk
//purpose : //purpose : Check if aShape is more local than this->_shape
//======================================================================= //=======================================================================
bool SMESH_HypoFilter::IsMoreLocalThanPredicate::IsOk(const SMESH_Hypothesis* aHyp, bool SMESH_HypoFilter::IsMoreLocalThanPredicate::IsOk(const SMESH_Hypothesis* aHyp,
@ -169,16 +169,23 @@ bool SMESH_HypoFilter::IsMoreLocalThanPredicate::IsOk(const SMESH_Hypothesis* aH
if ( SMESH_MesherHelper::IsSubShape( aShape, /*mainShape=*/_shape )) if ( SMESH_MesherHelper::IsSubShape( aShape, /*mainShape=*/_shape ))
return true; return true;
if ( aShape.ShapeType() == TopAbs_COMPOUND && if ( aShape.ShapeType() == TopAbs_COMPOUND &&
!SMESH_MesherHelper::IsSubShape( _shape, /*mainShape=*/aShape)) // issue 0020963 !SMESH_MesherHelper::IsSubShape( _shape, /*mainShape=*/aShape)) // issue 0020963
{ {
for ( int type = TopAbs_SOLID; type < TopAbs_SHAPE; ++type ) // [bos#22320] compound of FACEs is MORE local than compound of SOLIDs
if ( aHyp->GetDim() == SMESH_Gen::GetShapeDim( TopAbs_ShapeEnum( type ))) TopAbs_ShapeEnum givenType = SMESH_MesherHelper::GetGroupType( _shape );
for ( TopExp_Explorer exp( aShape, TopAbs_ShapeEnum( type )); exp.More(); exp.Next()) TopAbs_ShapeEnum hypType = SMESH_MesherHelper::GetGroupType( aShape );
if ( SMESH_MesherHelper::IsSubShape( exp.Current(), /*mainShape=*/_shape )) if ( SMESH_Gen::GetShapeDim( givenType ) > SMESH_Gen::GetShapeDim( hypType ))
return true; {
for ( int type = TopAbs_SOLID; type < TopAbs_SHAPE; ++type )
if ( aHyp->GetDim() == SMESH_Gen::GetShapeDim( TopAbs_ShapeEnum( type )))
for ( TopExp_Explorer exp( aShape, TopAbs_ShapeEnum( type )); exp.More(); exp.Next())
if ( SMESH_MesherHelper::IsSubShape( exp.Current(), /*mainShape=*/_shape ))
return true;
}
} }
// take forced sub-mesh priority into account
if ( _preferableShapes.Contains( aShape )) if ( _preferableShapes.Contains( aShape ))
return true; // issue 21559, Mesh_6 return true; // issue 21559, Mesh_6
@ -187,7 +194,7 @@ bool SMESH_HypoFilter::IsMoreLocalThanPredicate::IsOk(const SMESH_Hypothesis* aH
//======================================================================= //=======================================================================
//function : SMESH_HypoFilter //function : SMESH_HypoFilter
//purpose : //purpose :
//======================================================================= //=======================================================================
SMESH_HypoFilter::SMESH_HypoFilter() SMESH_HypoFilter::SMESH_HypoFilter()

View File

@ -110,6 +110,7 @@ SMESH_subMesh::SMESH_subMesh(int Id,
} }
_computeCost = 0; // how costly is to compute this sub-mesh _computeCost = 0; // how costly is to compute this sub-mesh
_realComputeCost = 0; _realComputeCost = 0;
_allowedSubShapes = nullptr;
} }
//============================================================================= //=============================================================================
@ -1478,11 +1479,14 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event)
if (_father->HasShapeToMesh() ) { if (_father->HasShapeToMesh() ) {
bool subComputed = false, subFailed = false; bool subComputed = false, subFailed = false;
if (!algo->OnlyUnaryInput()) { if (!algo->OnlyUnaryInput()) {
if ( event == COMPUTE /*&& // --- commented for bos#22320 to compute all sub-shapes at once if possible;
( algo->NeedDiscreteBoundary() || algo->SupportSubmeshes() )*/) // --- in case COMPUTE_SUBMESH, set of sub-shapes is limited
shape = getCollection( gen, algo, subComputed, subFailed, algo->SubMeshesToCompute()); // --- by calling SetAllowedSubShapes()
else // if ( event == COMPUTE )
subComputed = SubMeshesComputed( & subFailed ); // shape = getCollection( gen, algo, subComputed, subFailed, algo->SubMeshesToComput;
// else
// subComputed = SubMeshesComputed( & subFailed );
shape = getCollection( gen, algo, subComputed, subFailed, algo->SubMeshesToCompute());
} }
else { else {
subComputed = SubMeshesComputed(); subComputed = SubMeshesComputed();
@ -1610,8 +1614,9 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event)
((SMESHDS_Hypothesis*)hyps.front())->SaveTo( hypStr.Stream() ); ((SMESHDS_Hypothesis*)hyps.front())->SaveTo( hypStr.Stream() );
hypStr << " "; hypStr << " ";
} }
cout << _algo->GetName() cout << _father->GetSubMesh( subS.Current() )->GetId()
<< " " << _father->GetSubMesh( subS.Current() )->GetId() << " " << ( ret ? "OK" : "FAIL" )
<< " " << _algo->GetName()
<< " " << hypStr << endl; << " " << hypStr << endl;
} }
#endif #endif
@ -1747,6 +1752,8 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event)
break; break;
case COMPUTE: // nothing to do case COMPUTE: // nothing to do
break; break;
case COMPUTE_SUBMESH: // nothing to do
break;
case COMPUTE_CANCELED: // nothing to do case COMPUTE_CANCELED: // nothing to do
break; break;
case CLEAN: case CLEAN:
@ -2140,6 +2147,8 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * theGen,
const TopoDS_Shape& S = subMesh->_subShape; const TopoDS_Shape& S = subMesh->_subShape;
if ( S.ShapeType() != this->_subShape.ShapeType() ) if ( S.ShapeType() != this->_subShape.ShapeType() )
continue; continue;
if ( _allowedSubShapes && !_allowedSubShapes->IsEmpty() && !_allowedSubShapes->Contains( S ))
continue;
if ( subMesh == this ) if ( subMesh == this )
{ {
aBuilder.Add( aCompound, S ); aBuilder.Add( aCompound, S );

View File

@ -36,6 +36,7 @@
#include "Utils_SALOME_Exception.hxx" #include "Utils_SALOME_Exception.hxx"
#include <TopoDS_Shape.hxx> #include <TopoDS_Shape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <list> #include <list>
#include <map> #include <map>
@ -256,6 +257,12 @@ public:
bool IsMeshComputed() const; bool IsMeshComputed() const;
// check if _subMeshDS contains mesh elements unless _alwaysComputed==true // check if _subMeshDS contains mesh elements unless _alwaysComputed==true
/*!
* \brief Set sub-shapes that are allowed to compute at once by a multidimensional algo
*/
void SetAllowedSubShapes( const TopTools_IndexedMapOfShape* subShapes )
{ _allowedSubShapes = subShapes; }
/*! /*!
* \brief Allow algo->Compute() if a subshape of lower dim is meshed but * \brief Allow algo->Compute() if a subshape of lower dim is meshed but
* none mesh entity is bound to it * none mesh entity is bound to it
@ -344,6 +351,8 @@ protected:
// mesh several edges as a whole and leave some of them without mesh entities // mesh several edges as a whole and leave some of them without mesh entities
bool _alwaysComputed; bool _alwaysComputed;
const TopTools_IndexedMapOfShape* _allowedSubShapes; // allowed to be returned by getCollection()
}; };
#endif #endif

View File

@ -53,7 +53,7 @@ SMESHGUI_MeshOrderOp::SMESHGUI_MeshOrderOp()
{ {
myDlg = new SMESHGUI_MeshOrderDlg( desktop() ); myDlg = new SMESHGUI_MeshOrderDlg( desktop() );
myHelpFileName = "constructing_meshes.html#mesh-order-anchor"; myHelpFileName = "constructing_meshes.html#submesh-order-anchor";
} }
//================================================================================ //================================================================================

View File

@ -151,9 +151,10 @@ namespace
// Clear collected data // Clear collected data
void reset() void reset()
{ {
myFace2QuadMap.Clear();
StdMeshers_Quadrangle_2D::myQuadList.clear(); StdMeshers_Quadrangle_2D::myQuadList.clear();
StdMeshers_Quadrangle_2D::myHelper = nullptr; StdMeshers_Quadrangle_2D::myHelper = nullptr;
StdMeshers_Quadrangle_2D::myProxyMesh.reset();
myFace2QuadMap.Clear();
} }
//================================================================================ //================================================================================
@ -778,7 +779,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
SMESH_MesherHelper helper( theMesh ); SMESH_MesherHelper helper( theMesh );
myHelper = &helper; myHelper = &helper;
myPrevBottomSM = 0; myPrevBottomSM = 0;
TQuadrangleAlgo::Cleaner( TQuadrangleAlgo::instance( this )); TQuadrangleAlgo::Cleaner quadCleaner( TQuadrangleAlgo::instance( this ));
int nbSolids = helper.Count( theShape, TopAbs_SOLID, /*skipSame=*/false ); int nbSolids = helper.Count( theShape, TopAbs_SOLID, /*skipSame=*/false );
if ( nbSolids < 1 ) if ( nbSolids < 1 )
@ -848,6 +849,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
} }
TopTools_MapOfShape meshedSolids; TopTools_MapOfShape meshedSolids;
NCollection_DataMap< TopoDS_Shape, SMESH_subMesh* > meshedFace2AlgoSM;
list< Prism_3D::TPrismTopo > meshedPrism; list< Prism_3D::TPrismTopo > meshedPrism;
list< TopoDS_Face > suspectSourceFaces; list< TopoDS_Face > suspectSourceFaces;
TopTools_ListIteratorOfListOfShape solidIt; TopTools_ListIteratorOfListOfShape solidIt;
@ -871,6 +873,8 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
{ {
prism.Clear(); prism.Clear();
prism.myBottom = face; prism.myBottom = face;
if ( meshedFace2AlgoSM.IsBound( face ))
prism.myAlgoSM = meshedFace2AlgoSM.Find( face );
if ( !initPrism( prism, solid, selectBottom ) || if ( !initPrism( prism, solid, selectBottom ) ||
!compute( prism )) !compute( prism ))
return false; return false;
@ -880,6 +884,11 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
!myHelper->IsStructured( theMesh.GetSubMesh( prism.myTop ))) !myHelper->IsStructured( theMesh.GetSubMesh( prism.myTop )))
{ {
meshedFaces.push_front( prism.myTop ); meshedFaces.push_front( prism.myTop );
if ( prism.myAlgoSM && prism.myAlgoSM->GetAlgo() )
{
meshedFace2AlgoSM.Bind( prism.myTop, prism.myAlgoSM );
meshedFace2AlgoSM.Bind( prism.myBottom, prism.myAlgoSM );
}
} }
else else
{ {
@ -914,9 +923,18 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
solidList.Remove( solidIt ); solidList.Remove( solidIt );
continue; // already computed prism continue; // already computed prism
} }
if ( myHelper->IsBlock( solid )) { if ( myHelper->IsBlock( solid ))
solidIt.Next(); {
continue; // too trivial bool isStructBase = true;
if ( prismIt->myAlgoSM )
isStructBase = ( myHelper->IsSameElemGeometry( prismIt->myAlgoSM->GetSubMeshDS(),
SMDSGeom_QUADRANGLE ) &&
myHelper->IsStructured(prismIt->myAlgoSM ));
if ( isStructBase )
{
solidIt.Next();
continue; // too trivial
}
} }
// find a source FACE of the SOLID: it's a FACE sharing a bottom EDGE with wFace // find a source FACE of the SOLID: it's a FACE sharing a bottom EDGE with wFace
const TopoDS_Edge& wEdge = (*wQuad)->side[ QUAD_TOP_SIDE ].grid->Edge(0); const TopoDS_Edge& wEdge = (*wQuad)->side[ QUAD_TOP_SIDE ].grid->Edge(0);
@ -935,27 +953,41 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
} }
prism.Clear(); prism.Clear();
prism.myBottom = candidateF; prism.myBottom = candidateF;
prism.myAlgoSM = prismIt->myAlgoSM;
mySetErrorToSM = false; mySetErrorToSM = false;
if ( !myHelper->IsSubShape( candidateF, prismIt->myShape3D ) && if ( !myHelper->IsSubShape( candidateF, prismIt->myShape3D ) &&
myHelper ->IsSubShape( candidateF, solid ) && myHelper ->IsSubShape( candidateF, solid ) &&
!myHelper->GetMesh()->GetSubMesh( candidateF )->IsMeshComputed() && !myHelper->GetMesh()->GetSubMesh( candidateF )->IsMeshComputed() &&
initPrism( prism, solid, /*selectBottom=*/false ) && initPrism( prism, solid, /*selectBottom=*/false ) &&
!myHelper->GetMesh()->GetSubMesh( prism.myTop )->IsMeshComputed() && !myHelper->GetMesh()->GetSubMesh( prism.myTop )->IsMeshComputed() &&
!myHelper->GetMesh()->GetSubMesh( prism.myBottom )->IsMeshComputed() && !myHelper->GetMesh()->GetSubMesh( prism.myBottom )->IsMeshComputed() )
project2dMesh( sourceF, prism.myBottom ))
{ {
mySetErrorToSM = true; if ( project2dMesh( sourceF, prism.myBottom ))
if ( !compute( prism ))
return false;
SMESHDS_SubMesh* smDS = theMesh.GetMeshDS()->MeshElements( prism.myTop );
if ( !myHelper->IsSameElemGeometry( smDS, SMDSGeom_QUADRANGLE ))
{ {
meshedFaces.push_front( prism.myTop ); mySetErrorToSM = true;
meshedFaces.push_front( prism.myBottom ); if ( !compute( prism ))
selectBottom = false; return false;
SMESHDS_SubMesh* smDS = theMesh.GetMeshDS()->MeshElements( prism.myTop );
if ( !myHelper->IsSameElemGeometry( smDS, SMDSGeom_QUADRANGLE ))
{
meshedFaces.push_front( prism.myTop );
meshedFaces.push_front( prism.myBottom );
selectBottom = false;
if ( prism.myAlgoSM && prism.myAlgoSM->GetAlgo() )
{
meshedFace2AlgoSM.Bind( prism.myTop, prism.myAlgoSM );
meshedFace2AlgoSM.Bind( prism.myBottom, prism.myAlgoSM );
}
}
meshedPrism.push_back( prism );
meshedSolids.Add( solid );
}
else
{
meshedFaces.push_back( prism.myBottom );
if ( prism.myAlgoSM && prism.myAlgoSM->GetAlgo() )
meshedFace2AlgoSM.Bind( prism.myBottom, prism.myAlgoSM );
} }
meshedPrism.push_back( prism );
meshedSolids.Add( solid );
} }
InitComputeError(); InitComputeError();
} }
@ -1008,7 +1040,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
allSubMeComputed = smIt->next()->IsMeshComputed(); allSubMeComputed = smIt->next()->IsMeshComputed();
if ( allSubMeComputed ) if ( allSubMeComputed )
{ {
faceSM->ComputeStateEngine( SMESH_subMesh::COMPUTE ); faceSM->ComputeStateEngine( SMESH_subMesh::COMPUTE_SUBMESH );
if ( !faceSM->IsEmpty() ) { if ( !faceSM->IsEmpty() ) {
meshedFaces.push_front( face ); // higher priority meshedFaces.push_front( face ); // higher priority
selectBottom = true; selectBottom = true;
@ -1562,8 +1594,9 @@ bool StdMeshers_Prism_3D::computeBase(const Prism_3D::TPrismTopo& thePrism)
{ {
// find any applicable algorithm assigned to any FACE of the main shape // find any applicable algorithm assigned to any FACE of the main shape
std::vector< TopoDS_Shape > faces; std::vector< TopoDS_Shape > faces;
if ( myPrevBottomSM && if ( thePrism.myAlgoSM && thePrism.myAlgoSM->GetAlgo() )
myPrevBottomSM->GetAlgo()->IsApplicableToShape( thePrism.myBottom, /*all=*/false )) faces.push_back( thePrism.myAlgoSM->GetSubShape() );
if ( myPrevBottomSM && myPrevBottomSM->GetAlgo() )
faces.push_back( myPrevBottomSM->GetSubShape() ); faces.push_back( myPrevBottomSM->GetSubShape() );
TopExp_Explorer faceIt( mesh->GetShapeToMesh(), TopAbs_FACE ); TopExp_Explorer faceIt( mesh->GetShapeToMesh(), TopAbs_FACE );
@ -1588,7 +1621,7 @@ bool StdMeshers_Prism_3D::computeBase(const Prism_3D::TPrismTopo& thePrism)
while ( smIt->more() && subOK ) while ( smIt->more() && subOK )
{ {
SMESH_subMesh* sub = smIt->next(); SMESH_subMesh* sub = smIt->next();
sub->ComputeStateEngine( SMESH_subMesh::COMPUTE ); sub->ComputeStateEngine( SMESH_subMesh::COMPUTE_SUBMESH );
subOK = sub->IsMeshComputed(); subOK = sub->IsMeshComputed();
} }
if ( !subOK ) if ( !subOK )
@ -1596,23 +1629,31 @@ bool StdMeshers_Prism_3D::computeBase(const Prism_3D::TPrismTopo& thePrism)
} }
try { try {
OCC_CATCH_SIGNALS; OCC_CATCH_SIGNALS;
Hypothesis_Status status;
algo->CheckHypothesis( *mesh, faces[i], status );
algo->InitComputeError(); algo->InitComputeError();
algo->Compute( *mesh, botSM->GetSubShape() ); if ( algo->Compute( *mesh, botSM->GetSubShape() ))
{
myPrevBottomSM = thePrism.myAlgoSM = mesh->GetSubMesh( faces[i] );
break;
}
} }
catch (...) { catch (...) {
} }
} }
} }
} }
else
{
myPrevBottomSM = thePrism.myAlgoSM = botSM;
}
if ( botSM->IsEmpty() ) if ( botSM->IsEmpty() )
return error( COMPERR_BAD_INPUT_MESH, return error( COMPERR_BAD_INPUT_MESH,
TCom( "No mesher defined to compute the base face #") TCom( "No mesher defined to compute the base face #")
<< shapeID( thePrism.myBottom )); << shapeID( thePrism.myBottom ));
if ( botSM->GetAlgo() )
myPrevBottomSM = botSM;
return true; return true;
} }
@ -3504,6 +3545,7 @@ namespace Prism_3D
myBottomEdges.clear(); myBottomEdges.clear();
myNbEdgesInWires.clear(); myNbEdgesInWires.clear();
myWallQuads.clear(); myWallQuads.clear();
myAlgoSM = nullptr;
} }
//================================================================================ //================================================================================
@ -4806,7 +4848,7 @@ TopoDS_Edge StdMeshers_PrismAsBlock::TSideFace::GetEdge(const int iEdge) const
column = & ( myParamToColumnMap->rbegin()->second ); column = & ( myParamToColumnMap->rbegin()->second );
else else
column = & ( myParamToColumnMap->begin()->second ); column = & ( myParamToColumnMap->begin()->second );
if ( column->size() > 0 ) if ( column->size() > 1 )
edge = myHelper.GetSubShapeByNode( (*column)[ 1 ], meshDS ); edge = myHelper.GetSubShapeByNode( (*column)[ 1 ], meshDS );
if ( edge.IsNull() || edge.ShapeType() == TopAbs_VERTEX ) if ( edge.IsNull() || edge.ShapeType() == TopAbs_VERTEX )
node = column->front(); node = column->front();

View File

@ -106,6 +106,7 @@ namespace Prism_3D
std::list< int > myNbEdgesInWires; std::list< int > myNbEdgesInWires;
bool myNotQuadOnTop; bool myNotQuadOnTop;
mutable SMESH_subMesh* myAlgoSM; // sub-mesh with algo which computed myBottom
size_t NbWires() const { return myNbEdgesInWires.size(); } size_t NbWires() const { return myNbEdgesInWires.size(); }