// File : SMESH_Gen.cxx
// Author : Paul RASCLE, EDF
// Module : SMESH
-// $Header$
#include "SMESH_Gen.hxx"
#include "SMESH_subMesh.hxx"
MESSAGE("SMESH_Gen::SMESH_Gen");
_localId = 0;
_hypId = 0;
+ _segmentation = 10;
}
//=============================================================================
*/
//=============================================================================
-bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
- const TopoDS_Shape & aShape,
- const bool anUpward)
+bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape,
+ const bool anUpward,
+ const ::MeshDimension aDim,
+ TSetOfInt* aShapesId)
{
MESSAGE("SMESH_Gen::Compute");
SMESH_subMesh* smToCompute = smIt->next();
// do not mesh vertices of a pseudo shape
- if ( !aMesh.HasShapeToMesh() &&
- smToCompute->GetSubShape().ShapeType() == TopAbs_VERTEX )
+ const TopAbs_ShapeEnum aShType = smToCompute->GetSubShape().ShapeType();
+ if ( !aMesh.HasShapeToMesh() && aShType == TopAbs_VERTEX )
continue;
+ // check for preview dimension limitations
+ if ( aShapesId && GetShapeDim( aShType ) > (int)aDim )
+ {
+ // clear compute state to not show previous compute errors
+ // if preview invoked less dimension less than previous
+ smToCompute->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+ continue;
+ }
+
if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
// we check all the submeshes here and detect if any of them failed to compute
if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE)
ret = false;
+ else if ( aShapesId )
+ aShapesId->insert( smToCompute->GetId() );
}
return ret;
}
continue;
const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
- if ( GetShapeDim( aSubShape ) < 1 ) break;
+ const int aShapeDim = GetShapeDim( aSubShape );
+ if ( aShapeDim < 1 ) break;
+
+ // check for preview dimension limitations
+ if ( aShapesId && aShapeDim > (int)aDim )
+ continue;
SMESH_Algo* algo = GetAlgo( aMesh, aSubShape );
if ( algo && !algo->NeedDescretBoundary() )
if ( algo->SupportSubmeshes() )
smWithAlgoSupportingSubmeshes.push_back( smToCompute );
else
+ {
smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+ if ( aShapesId )
+ aShapesId->insert( smToCompute->GetId() );
+ }
}
}
// ------------------------------------------------------------
SMESH_subMesh* smToCompute = smIt->next();
const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
- if ( aSubShape.ShapeType() == TopAbs_VERTEX ) continue;
-
+ const int aShapeDim = GetShapeDim( aSubShape );
+ //if ( aSubShape.ShapeType() == TopAbs_VERTEX ) continue;
+ if ( aShapeDim < 1 ) continue;
+
+ // check for preview dimension limitations
+ if ( aShapesId && GetShapeDim( aSubShape.ShapeType() ) > (int)aDim )
+ continue;
+
SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
filter
.And( SMESH_HypoFilter::IsApplicableTo( aSubShape ))
if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) {
SMESH_Hypothesis::Hypothesis_Status status;
if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status ))
- // mesh a lower smToCompute
- Compute( aMesh, aSubShape );
+ // mesh a lower smToCompute starting from vertices
+ Compute( aMesh, aSubShape, /*anUpward=*/true, aDim, aShapesId );
}
}
}
{
sm = *subIt;
if ( sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
+ {
+ const TopAbs_ShapeEnum aShType = sm->GetSubShape().ShapeType();
+ // check for preview dimension limitations
+ if ( aShapesId && GetShapeDim( aShType ) > (int)aDim )
+ continue;
+
sm->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+ if ( aShapesId )
+ aShapesId->insert( sm->GetId() );
+ }
}
// -----------------------------------------------
// mesh the rest subshapes starting from vertices
// -----------------------------------------------
- ret = Compute( aMesh, aShape, /*anUpward=*/true );
+ ret = Compute( aMesh, aShape, /*anUpward=*/true, aDim, aShapesId );
}
MESSAGE( "VSR - SMESH_Gen::Compute() finished, OK = " << ret);
return ret;
}
+
+//=============================================================================
+/*!
+ * Evaluate a mesh
+ */
+//=============================================================================
+
+bool SMESH_Gen::Evaluate(SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap,
+ const bool anUpward,
+ TSetOfInt* aShapesId)
+{
+ MESSAGE("SMESH_Gen::Evaluate");
+
+ bool ret = true;
+
+ SMESH_subMesh *sm = aMesh.GetSubMesh(aShape);
+
+ const bool includeSelf = true;
+ const bool complexShapeFirst = true;
+ SMESH_subMeshIteratorPtr smIt;
+
+ if ( anUpward ) { // is called from below code here
+ // -----------------------------------------------
+ // mesh all the subshapes starting from vertices
+ // -----------------------------------------------
+ smIt = sm->getDependsOnIterator(includeSelf, !complexShapeFirst);
+ while ( smIt->more() ) {
+ SMESH_subMesh* smToCompute = smIt->next();
+
+ // do not mesh vertices of a pseudo shape
+ const TopAbs_ShapeEnum aShType = smToCompute->GetSubShape().ShapeType();
+ //if ( !aMesh.HasShapeToMesh() && aShType == TopAbs_VERTEX )
+ // continue;
+ if ( !aMesh.HasShapeToMesh() ) {
+ if( aShType == TopAbs_VERTEX || aShType == TopAbs_WIRE ||
+ aShType == TopAbs_SHELL )
+ continue;
+ }
+
+ smToCompute->Evaluate(aResMap);
+ if( aShapesId )
+ aShapesId->insert( smToCompute->GetId() );
+ }
+ return ret;
+ }
+ else {
+ // -----------------------------------------------------------------
+ // apply algos that DO NOT require descretized boundaries and DO NOT
+ // support submeshes, starting from the most complex shapes
+ // and collect submeshes with algos that DO support submeshes
+ // -----------------------------------------------------------------
+ list< SMESH_subMesh* > smWithAlgoSupportingSubmeshes;
+ smIt = sm->getDependsOnIterator(includeSelf, complexShapeFirst);
+ while ( smIt->more() ) {
+ SMESH_subMesh* smToCompute = smIt->next();
+ const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
+ const int aShapeDim = GetShapeDim( aSubShape );
+ if ( aShapeDim < 1 ) break;
+
+ SMESH_Algo* algo = GetAlgo( aMesh, aSubShape );
+ if ( algo && !algo->NeedDescretBoundary() ) {
+ if ( algo->SupportSubmeshes() ) {
+ smWithAlgoSupportingSubmeshes.push_back( smToCompute );
+ }
+ else {
+ smToCompute->Evaluate(aResMap);
+ if ( aShapesId )
+ aShapesId->insert( smToCompute->GetId() );
+ }
+ }
+ }
+ // ------------------------------------------------------------
+ // compute submeshes under shapes with algos that DO NOT require
+ // descretized boundaries and DO support submeshes
+ // ------------------------------------------------------------
+ list< SMESH_subMesh* >::reverse_iterator subIt, subEnd;
+ subIt = smWithAlgoSupportingSubmeshes.rbegin();
+ subEnd = smWithAlgoSupportingSubmeshes.rend();
+ // start from lower shapes
+ for ( ; subIt != subEnd; ++subIt ) {
+ sm = *subIt;
+
+ // get a shape the algo is assigned to
+ TopoDS_Shape algoShape;
+ if ( !GetAlgo( aMesh, sm->GetSubShape(), & algoShape ))
+ continue; // strange...
+
+ // look for more local algos
+ smIt = sm->getDependsOnIterator(!includeSelf, !complexShapeFirst);
+ while ( smIt->more() ) {
+ SMESH_subMesh* smToCompute = smIt->next();
+
+ const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
+ const int aShapeDim = GetShapeDim( aSubShape );
+ if ( aShapeDim < 1 ) continue;
+
+ //const TopAbs_ShapeEnum aShType = smToCompute->GetSubShape().ShapeType();
+
+ SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
+ filter
+ .And( SMESH_HypoFilter::IsApplicableTo( aSubShape ))
+ .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape ));
+
+ if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) {
+ SMESH_Hypothesis::Hypothesis_Status status;
+ if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status ))
+ // mesh a lower smToCompute starting from vertices
+ Evaluate( aMesh, aSubShape, aResMap, /*anUpward=*/true, aShapesId );
+ }
+ }
+ }
+ // ----------------------------------------------------------
+ // apply the algos that do not require descretized boundaries
+ // ----------------------------------------------------------
+ for ( subIt = smWithAlgoSupportingSubmeshes.rbegin(); subIt != subEnd; ++subIt )
+ {
+ sm = *subIt;
+ sm->Evaluate(aResMap);
+ if ( aShapesId )
+ aShapesId->insert( sm->GetId() );
+ }
+
+ // -----------------------------------------------
+ // mesh the rest subshapes starting from vertices
+ // -----------------------------------------------
+ ret = Evaluate( aMesh, aShape, aResMap, /*anUpward=*/true, aShapesId );
+ }
+
+ MESSAGE( "VSR - SMESH_Gen::Evaluate() finished, OK = " << ret);
+ return ret;
+}
+
+
//=======================================================================
//function : checkConformIgnoredAlgos
//purpose :
const SMESH_Algo* aGlobIgnoAlgo,
const SMESH_Algo* aLocIgnoAlgo,
bool & checkConform,
- map<int, SMESH_subMesh*>& aCheckedMap,
+ set<SMESH_subMesh*>& aCheckedMap,
list< SMESH_Gen::TAlgoStateError > & theErrors)
{
ASSERT( aSubMesh );
}
// sub-algos will be hidden by a local <algo>
- const map<int, SMESH_subMesh*>& smMap = aSubMesh->DependsOn();
- map<int, SMESH_subMesh*>::const_reverse_iterator revItSub;
+ SMESH_subMeshIteratorPtr revItSub =
+ aSubMesh->getDependsOnIterator( /*includeSelf=*/false, /*complexShapeFirst=*/true);
bool checkConform2 = false;
- for ( revItSub = smMap.rbegin(); revItSub != smMap.rend(); revItSub++)
+ while ( revItSub->more() )
{
- checkConformIgnoredAlgos (aMesh, (*revItSub).second, aGlobIgnoAlgo,
+ SMESH_subMesh* sm = revItSub->next();
+ checkConformIgnoredAlgos (aMesh, sm, aGlobIgnoAlgo,
algo, checkConform2, aCheckedMap, theErrors);
- int key = (*revItSub).first;
- SMESH_subMesh* sm = (*revItSub).second;
- if ( aCheckedMap.find( key ) == aCheckedMap.end() )
- {
- aCheckedMap[ key ] = sm;
- }
+ aCheckedMap.insert( sm );
}
}
}
const int aTopAlgoDim,
bool* globalChecked,
const bool checkNoAlgo,
- map<int, SMESH_subMesh*>& aCheckedMap,
+ set<SMESH_subMesh*>& aCheckedMap,
list< SMESH_Gen::TAlgoStateError > & theErrors)
{
if ( aSubMesh->GetSubShape().ShapeType() == TopAbs_VERTEX)
if (!algo->NeedDescretBoundary() || isTopLocalAlgo)
{
bool checkNoAlgo2 = ( algo->NeedDescretBoundary() );
- const map<int, SMESH_subMesh*>& subMeshes = aSubMesh->DependsOn();
- map<int, SMESH_subMesh*>::const_iterator itsub;
- for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
+ SMESH_subMeshIteratorPtr itsub = aSubMesh->getDependsOnIterator( /*includeSelf=*/false,
+ /*complexShapeFirst=*/false);
+ while ( itsub->more() )
{
// sub-meshes should not be checked further more
- int key = (*itsub).first;
- SMESH_subMesh* sm = (*itsub).second;
- if ( aCheckedMap.find( key ) == aCheckedMap.end() )
- aCheckedMap[ key ] = sm;
+ SMESH_subMesh* sm = itsub->next();
+ aCheckedMap.insert( sm );
if (isTopLocalAlgo)
{
}
}
- const map<int, SMESH_subMesh*>& smMap = sm->DependsOn();
- map<int, SMESH_subMesh*>::const_reverse_iterator revItSub = smMap.rbegin();
- map<int, SMESH_subMesh*> aCheckedMap;
+ set<SMESH_subMesh*> aCheckedSubs;
bool checkConform = ( !theMesh.IsNotConformAllowed() );
- int aKey = 1;
- SMESH_subMesh* smToCheck = sm;
// loop on theShape and its sub-shapes
- while ( smToCheck )
+ SMESH_subMeshIteratorPtr revItSub = sm->getDependsOnIterator( /*includeSelf=*/true,
+ /*complexShapeFirst=*/true);
+ while ( revItSub->more() )
{
+ SMESH_subMesh* smToCheck = revItSub->next();
if ( smToCheck->GetSubShape().ShapeType() == TopAbs_VERTEX)
break;
- if ( aCheckedMap.find( aKey ) == aCheckedMap.end() )
+ if ( aCheckedSubs.insert( smToCheck ).second ) // not yet checked
if (!checkConformIgnoredAlgos (theMesh, smToCheck, aGlobIgnoAlgo,
- 0, checkConform, aCheckedMap, theErrors))
+ 0, checkConform, aCheckedSubs, theErrors))
ret = false;
if ( smToCheck->GetAlgoState() != SMESH_subMesh::NO_ALGO )
hasAlgo = true;
-
- // next subMesh
- if (revItSub != smMap.rend())
- {
- aKey = (*revItSub).first;
- smToCheck = (*revItSub).second;
- revItSub++;
- }
- else
- {
- smToCheck = 0;
- }
-
}
// ----------------------------------------------------------------
break;
}
}
- aCheckedMap.clear();
- smToCheck = sm;
- revItSub = smMap.rbegin();
bool checkNoAlgo = theMesh.HasShapeToMesh() ? bool( aTopAlgoDim ) : false;
bool globalChecked[] = { false, false, false, false };
// loop on theShape and its sub-shapes
- while ( smToCheck )
+ aCheckedSubs.clear();
+ revItSub = sm->getDependsOnIterator( /*includeSelf=*/true, /*complexShapeFirst=*/true);
+ while ( revItSub->more() )
{
+ SMESH_subMesh* smToCheck = revItSub->next();
if ( smToCheck->GetSubShape().ShapeType() == TopAbs_VERTEX)
break;
- if ( aCheckedMap.find( aKey ) == aCheckedMap.end() )
+ if ( aCheckedSubs.insert( smToCheck ).second ) // not yet checked
if (!checkMissing (this, theMesh, smToCheck, aTopAlgoDim,
- globalChecked, checkNoAlgo, aCheckedMap, theErrors))
+ globalChecked, checkNoAlgo, aCheckedSubs, theErrors))
{
ret = false;
if (smToCheck->GetAlgoState() == SMESH_subMesh::NO_ALGO )
checkNoAlgo = false;
}
-
- // next subMesh
- if (revItSub != smMap.rend())
- {
- aKey = (*revItSub).first;
- smToCheck = (*revItSub).second;
- revItSub++;
- }
- else
- smToCheck = 0;
}
if ( !hasAlgo ) {
return myStudyContext;
}
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
+// //=============================================================================
+// /*!
+// *
+// */
+// //=============================================================================
-void SMESH_Gen::Save(int studyId, const char *aUrlOfFile)
-{
-}
+// void SMESH_Gen::Save(int studyId, const char *aUrlOfFile)
+// {
+// }
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
+// //=============================================================================
+// /*!
+// *
+// */
+// //=============================================================================
-void SMESH_Gen::Load(int studyId, const char *aUrlOfFile)
-{
-}
+// void SMESH_Gen::Load(int studyId, const char *aUrlOfFile)
+// {
+// }
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
+// //=============================================================================
+// /*!
+// *
+// */
+// //=============================================================================
-void SMESH_Gen::Close(int studyId)
-{
-}
+// void SMESH_Gen::Close(int studyId)
+// {
+// }
//=============================================================================
/*!
if ( dim.empty() )
{
dim.resize( TopAbs_SHAPE, -1 );
- dim[ TopAbs_COMPOUND ] = 3;
- dim[ TopAbs_COMPSOLID ] = 3;
- dim[ TopAbs_SOLID ] = 3;
- dim[ TopAbs_SHELL ] = 3;
- dim[ TopAbs_FACE ] = 2;
- dim[ TopAbs_WIRE ] = 1;
- dim[ TopAbs_EDGE ] = 1;
- dim[ TopAbs_VERTEX ] = 0;
+ dim[ TopAbs_COMPOUND ] = MeshDim_3D;
+ dim[ TopAbs_COMPSOLID ] = MeshDim_3D;
+ dim[ TopAbs_SOLID ] = MeshDim_3D;
+ dim[ TopAbs_SHELL ] = MeshDim_3D;
+ dim[ TopAbs_FACE ] = MeshDim_2D;
+ dim[ TopAbs_WIRE ] = MeshDim_1D;
+ dim[ TopAbs_EDGE ] = MeshDim_1D;
+ dim[ TopAbs_VERTEX ] = MeshDim_0D;
}
return dim[ aShapeType ];
}
// File : SMESH_Gen.hxx
// Author : Paul RASCLE, EDF
// Module : SMESH
-// $Header$
//
+
#ifndef _SMESH_GEN_HXX_
#define _SMESH_GEN_HXX_
#include <TopoDS_Shape.hxx>
#include <map>
+#include <list>
class SMESHDS_Document;
SMESHDS_Document * myDocument;
} StudyContextStruct;
+typedef std::set<int> TSetOfInt;
+
class SMESH_EXPORT SMESH_Gen
{
- public:
+public:
SMESH_Gen();
~SMESH_Gen();
/*!
* \brief Computes aMesh on aShape
* \param anUpward - compute from vertices up to more complex shape (internal usage)
+ * \param aDim - upper level dimension of the mesh computation
+ * \param aShapesId - list of shapes with computed mesh entities (elements or nodes)
* \retval bool - true if none submesh failed to compute
*/
- bool Compute(::SMESH_Mesh & aMesh,
- const TopoDS_Shape & aShape,
- const bool anUpward=false);
+ bool Compute(::SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape,
+ const bool anUpward=false,
+ const ::MeshDimension aDim=::MeshDim_3D,
+ TSetOfInt* aShapesId=0);
+
+ /*!
+ * \brief evaluates size of prospective mesh on a shape
+ * \param aMesh - the mesh
+ * \param aShape - the shape
+ * \param aResMap - map for prospective numbers of elements
+ * \retval bool - is a success
+ */
+ bool Evaluate(::SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap,
+ const bool anUpward=false,
+ TSetOfInt* aShapesId=0);
bool CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
// notify on bad state of attached algos, return false
// if Compute() would fail because of some algo bad state
-
+ /*!
+ * \brief Sets number of segments per diagonal of boundary box of geometry by which
+ * default segment length of appropriate 1D hypotheses is defined
+ */
+ void SetBoundaryBoxSegmentation( int theNbSegments ) { _segmentation = theNbSegments; }
+ int GetBoundaryBoxSegmentation() const { return _segmentation; }
+ /*!
+ * \brief Sets default number of segments per edge
+ */
+ void SetDefaultNbSegments(int nb) { _nbSegments = nb; }
+ int GetDefaultNbSegments() const { return _nbSegments; }
+
struct TAlgoStateError
{
TAlgoStateErrorName _name;
SMESH_Algo* GetAlgo(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, TopoDS_Shape* assignedTo=0);
static bool IsGlobalHypothesis(const SMESH_Hypothesis* theHyp, SMESH_Mesh& aMesh);
- // inherited methods from SALOMEDS::Driver
-
- void Save(int studyId, const char *aUrlOfFile);
- void Load(int studyId, const char *aUrlOfFile);
- void Close(int studyId);
- const char *ComponentDataType();
-
- const char *IORToLocalPersistentID(const char *IORString, bool & IsAFile);
- const char *LocalPersistentIDToIOR(const char *aLocalPersistentID);
-
int GetANewId();
std::map < int, SMESH_Algo * >_mapAlgo;
std::map < int, SMESH_2D_Algo * >_map2D_Algo;
std::map < int, SMESH_3D_Algo * >_map3D_Algo;
- private:
+private:
- int _localId; // unique Id of created objects, within SMESH_Gen entity
+ int _localId; // unique Id of created objects, within SMESH_Gen entity
std::map < int, StudyContextStruct * >_mapStudyContext;
// hypotheses managing
int _hypId;
+
+ // number of segments per diagonal of boundary box of geometry by which
+ // default segment length of appropriate 1D hypotheses is defined
+ int _segmentation;
+ // default of segments
+ int _nbSegments;
};
#endif