<li>\ref constructing_submeshes_page</li>
<li>\ref building_compounds_page</li>
<li>\ref editing_meshes_page</li>
+<li>\ref preview_meshes_page</li>
</ul>
<li>\subpage viewing_meshes_page</li>
<ul>
--- /dev/null
+/*!
+
+\page preview_meshes_page Preview and Compute meshes
+
+Before whole mesh computation it is allowed to see the mesh preview.
+When mesh object is already created and all hypotheses assigned,
+select your mesh in the <b>Object Browser</b>. From the
+\b Mesh menu select \b Preview or click "Preview" button of the
+toolbar or activate "Preview" item from pop-up menu.
+
+\image html mesh_precompute.png
+<center><em>"Preview" button</em></center>
+
+The Mesh Preview dialog box appears. In this dialog box you can select
+preview mode <b>1D mesh</b> or <b>2D mesh</b> depending on assigned
+hypotheses to mesh.
+
+The 1D mesh preview shows as nodes computed on geometry edges
+
+\image html preview_mesh_1D.png
+
+The 2D mesh preview shows edge mesh elements, computed on geometry faces
+
+\image html preview_mesh_2D.png
+
+Pressing <b>Compute</b> button leads to whole mesh computation
+process.
+During exit from Preview dialog box, the question about storage temporary
+created mesh elements appers:
+
+\image html preview_tmp_data.png
+
+Note, that computed temporary mesh elements can be reused during next
+mesh computation process.
+
+*/
in GEOM::GEOM_Object theSubObject )
raises ( SALOME::SALOME_Exception );
+ /*!
+ * Calculate Mesh as preview till indicated dimension
+ * First, verify list of hypothesis associated with the subShape.
+ * Return mesh preview structure
+ */
+ MeshPreviewStruct Precompute( in SMESH_Mesh theMesh,
+ in GEOM::GEOM_Object theSubObject,
+ in Dimension theDimension,
+ inout long_array theShapesId )
+ raises ( SALOME::SALOME_Exception );
+
/*!
* Return errors of hypotheses definintion
* algo_error_array is empty if everything is OK
void Clear()
raises (SALOME::SALOME_Exception);
+ /*!
+ * Remove all nodes and elements of submesh
+ */
+ void ClearSubMesh(in long ShapeID)
+ raises (SALOME::SALOME_Exception);
+
/*!
* Get the subMesh object associated to a subShape. The subMesh object
* gives access to nodes and elements IDs.
*/
//=============================================================================
-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 )
+ 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 ))
SMESH_Hypothesis::Hypothesis_Status status;
if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status ))
// mesh a lower smToCompute starting from vertices
- Compute( aMesh, aSubShape, /*anUpward=*/true );
+ Compute( aMesh, aSubShape, /*anUpward=*/true, aDim, aShapesId );
}
}
}
// ----------------------------------------------------------
for ( subIt = smWithAlgoSupportingSubmeshes.rbegin(); subIt != subEnd; ++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);
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 ];
}
#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:
/*!
* \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);
bool CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
// notify on bad state of attached algos, return false
class TopoDS_Shape;
class SMESH_Mesh;
+enum MeshDimension // dimension of mesh
+{
+ MeshDim_0D,
+ MeshDim_1D,
+ MeshDim_2D,
+ MeshDim_3D
+};
+
class SMESH_EXPORT SMESH_Hypothesis: public SMESHDS_Hypothesis
{
public:
// }
}
+//=======================================================================
+/*!
+ * \brief Remove all nodes and elements of indicated shape
+ */
+//=======================================================================
+
+void SMESH_Mesh::ClearSubMesh(const int theShapeId)
+{
+ // clear sub-meshes; get ready to re-compute as a side-effect
+ if ( SMESH_subMesh *sm = GetSubMeshContaining( theShapeId ) )
+ {
+ SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,
+ /*complexShapeFirst=*/false);
+ while ( smIt->more() )
+ {
+ sm = smIt->next();
+ TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType();
+ if ( shapeType == TopAbs_VERTEX || shapeType < TopAbs_SOLID )
+ // all other shapes depends on vertices so they are already cleaned
+ sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
+ // to recompute even if failed
+ sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+ }
+ }
+}
+
//=======================================================================
//function : UNVToMesh
//purpose :
*/
void Clear();
+ /*!
+ * \brief Remove all nodes and elements of indicated shape
+ */
+ void ClearSubMesh(const int theShapeId);
+
int UNVToMesh(const char* theFileName);
/*!
* consult DriverMED_R_SMESHDS_Mesh::ReadStatus for returned value
TNodeXYZ( const SMDS_MeshNode* n ):gp_XYZ( n->X(), n->Y(), n->Z() ) {}
};
-typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink;
-
-//=======================================================================
-/*!
- * \brief A sorted pair of nodes
- */
-//=======================================================================
-
-struct TLink: public NLink
-{
- TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 )
- { if ( n1->GetID() < n2->GetID() ) std::swap( first, second ); }
- TLink(const NLink& link ):NLink( link )
- { if ( first->GetID() < second->GetID() ) std::swap( first, second ); }
-};
-
//=======================================================================
//function : SMESH_MeshEditor
//purpose :
// 1. map of elements with their linkIDs
// 2. map of linkIDs with their elements
- map< TLink, list< const SMDS_MeshElement* > > mapLi_listEl;
- map< TLink, list< const SMDS_MeshElement* > >::iterator itLE;
- map< const SMDS_MeshElement*, set< TLink > > mapEl_setLi;
- map< const SMDS_MeshElement*, set< TLink > >::iterator itEL;
+ map< SMESH_TLink, list< const SMDS_MeshElement* > > mapLi_listEl;
+ map< SMESH_TLink, list< const SMDS_MeshElement* > >::iterator itLE;
+ map< const SMDS_MeshElement*, set< SMESH_TLink > > mapEl_setLi;
+ map< const SMDS_MeshElement*, set< SMESH_TLink > >::iterator itEL;
TIDSortedElemSet::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
// fill maps
for ( i = 0; i < 3; i++ ) {
- TLink link( aNodes[i], aNodes[i+1] );
+ SMESH_TLink link( aNodes[i], aNodes[i+1] );
// check if elements sharing a link can be fused
itLE = mapLi_listEl.find( link );
if ( itLE != mapLi_listEl.end() ) {
int nbElems = (*itLE).second.size();
if ( nbElems < 2 ) {
const SMDS_MeshElement* elem = (*itLE).second.front();
- TLink link = (*itLE).first;
+ SMESH_TLink link = (*itLE).first;
mapEl_setLi[ elem ].erase( link );
if ( mapEl_setLi[ elem ].empty() )
mapEl_setLi.erase( elem );
// search elements to fuse starting from startElem or links of elements
// fused earlyer - startLinks
- list< TLink > startLinks;
+ list< SMESH_TLink > startLinks;
while ( startElem || !startLinks.empty() ) {
while ( !startElem && !startLinks.empty() ) {
// Get an element to start, by a link
- TLink linkId = startLinks.front();
+ SMESH_TLink linkId = startLinks.front();
startLinks.pop_front();
itLE = mapLi_listEl.find( linkId );
if ( itLE != mapLi_listEl.end() ) {
if ( startElem ) {
// Get candidates to be fused
const SMDS_MeshElement *tr1 = startElem, *tr2 = 0, *tr3 = 0;
- const TLink *link12, *link13;
+ const SMESH_TLink *link12, *link13;
startElem = 0;
ASSERT( mapEl_setLi.find( tr1 ) != mapEl_setLi.end() );
- set< TLink >& setLi = mapEl_setLi[ tr1 ];
+ set< SMESH_TLink >& setLi = mapEl_setLi[ tr1 ];
ASSERT( !setLi.empty() );
- set< TLink >::iterator itLi;
+ set< SMESH_TLink >::iterator itLi;
for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ )
{
- const TLink & link = (*itLi);
+ const SMESH_TLink & link = (*itLi);
itLE = mapLi_listEl.find( link );
if ( itLE == mapLi_listEl.end() )
continue;
}
// add other links of elem to list of links to re-start from
- set< TLink >& links = mapEl_setLi[ elem ];
- set< TLink >::iterator it;
+ set< SMESH_TLink >& links = mapEl_setLi[ elem ];
+ set< SMESH_TLink >::iterator it;
for ( it = links.begin(); it != links.end(); it++ ) {
- const TLink& link2 = (*it);
+ const SMESH_TLink& link2 = (*it);
if ( link2 != link )
startLinks.push_back( link2 );
}
// fix nodes on mesh boundary
if ( checkBoundaryNodes ) {
- typedef pair<const SMDS_MeshNode*, const SMDS_MeshNode*> TLink;
- map< TLink, int > linkNbMap; // how many times a link encounters in elemsOnFace
- map< TLink, int >::iterator link_nb;
+ map< NLink, int > linkNbMap; // how many times a link encounters in elemsOnFace
+ map< NLink, int >::iterator link_nb;
// put all elements links to linkNbMap
list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();
for ( ; elemIt != elemsOnFace.end(); ++elemIt ) {
const SMDS_MeshNode* curNode, *prevNode = elem->GetNode( nbn );
for ( int iN = 0; iN < nbn; ++iN ) {
curNode = elem->GetNode( iN );
- TLink link;
+ NLink link;
if ( curNode < prevNode ) link = make_pair( curNode , prevNode );
else link = make_pair( prevNode , curNode );
prevNode = curNode;
if ( theSecondNode1 != theSecondNode2 )
nReplaceMap.insert( make_pair( theSecondNode1, theSecondNode2 ));
- set< TLink > linkSet; // set of nodes where order of nodes is ignored
- linkSet.insert( TLink( theFirstNode1, theSecondNode1 ));
+ set< SMESH_TLink > linkSet; // set of nodes where order of nodes is ignored
+ linkSet.insert( SMESH_TLink( theFirstNode1, theSecondNode1 ));
list< NLink > linkList[2];
linkList[0].push_back( NLink( theFirstNode1, theSecondNode1 ));
for ( int i = 0; i < nbN; i++ )
{
const SMDS_MeshNode* n2 = f0->GetNode( i );
- pair< set< TLink >::iterator, bool > iter_isnew =
- linkSet.insert( TLink( n1, n2 ));
+ pair< set< SMESH_TLink >::iterator, bool > iter_isnew =
+ linkSet.insert( SMESH_TLink( n1, n2 ));
if ( !iter_isnew.second ) { // already in a set: no need to process
linkSet.erase( iter_isnew.first );
}
std::list<const SMDS_MeshElement*> > TElemOfElemListMap;
typedef std::map<const SMDS_MeshNode*, const SMDS_MeshNode*> TNodeNodeMap;
+
+typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink;
+
+//=======================================================================
+/*!
+ * \brief A sorted pair of nodes
+ */
+//=======================================================================
+
+struct SMESH_TLink: public NLink
+{
+ SMESH_TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 )
+ { if ( n1->GetID() < n2->GetID() ) std::swap( first, second ); }
+ SMESH_TLink(const NLink& link ):NLink( link )
+ { if ( first->GetID() < second->GetID() ) std::swap( first, second ); }
+};
+
+
class SMDS_MeshFace;
class SMDS_MeshNode;
class gp_Ax1;