-// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, 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.
+// 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
#include "Utils_ExceptHandlers.hxx"
#include <TopoDS_Iterator.hxx>
-#include <LDOMParser.hxx>
+#include <TopoDS.hxx>
#include "memoire.h"
-#ifdef WNT
+#ifdef WIN32
#include <windows.h>
-#endif\r
+#endif
using namespace std;
+//#include <vtkDebugLeaks.h>
+
+
//=============================================================================
/*!
* Constructor
SMESH_Gen::SMESH_Gen()
{
- MESSAGE("SMESH_Gen::SMESH_Gen");
- _localId = 0;
- _hypId = 0;
- _segmentation = _nbSegments = 10;
- SMDS_Mesh::_meshList.clear();
- MESSAGE(SMDS_Mesh::_meshList.size());
- _counters = new counters(100);
-#ifdef WITH_SMESH_CANCEL_COMPUTE
- _compute_canceled = false;
- _sm_current = NULL;
-#endif
+ _localId = 0;
+ _hypId = 0;
+ _segmentation = _nbSegments = 10;
+ SMDS_Mesh::_meshList.clear();
+ _compute_canceled = false;
+ //vtkDebugLeaks::SetExitError(0);
}
//=============================================================================
SMESH_Gen::~SMESH_Gen()
{
- MESSAGE("SMESH_Gen::~SMESH_Gen");
+ std::map < int, StudyContextStruct * >::iterator i_sc = _mapStudyContext.begin();
+ for ( ; i_sc != _mapStudyContext.end(); ++i_sc )
+ {
+ delete i_sc->second->myDocument;
+ delete i_sc->second;
+ }
}
//=============================================================================
throw(SALOME_Exception)
{
Unexpect aCatch(SalomeException);
- MESSAGE("SMESH_Gen::CreateMesh");
// Get studyContext, create it if it does'nt exist, with a SMESHDS_Document
StudyContextStruct *aStudyContext = GetStudyContext(theStudyId);
}
//=============================================================================
-/*!
+/*
* Compute a mesh
*/
//=============================================================================
bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
const TopoDS_Shape & aShape,
- const bool anUpward,
- const ::MeshDimension aDim,
- TSetOfInt* aShapesId)
+ const bool aShapeOnly /*=false*/,
+ const bool anUpward /*=false*/,
+ const ::MeshDimension aDim /*=::MeshDim_3D*/,
+ TSetOfInt* aShapesId /*=0*/)
{
- MESSAGE("SMESH_Gen::Compute");
MEMOSTAT;
bool ret = true;
SMESH_subMeshIteratorPtr smIt;
- if ( anUpward ) // is called from below code here
+ // Fix of Issue 22150. Due to !BLSURF->OnlyUnaryInput(), BLSURF computes edges
+ // that must be computed by Projection 1D-2D when Projection asks to compute
+ // one face only.
+ SMESH_subMesh::compute_event computeEvent =
+ aShapeOnly ? SMESH_subMesh::COMPUTE_SUBMESH : SMESH_subMesh::COMPUTE;
+
+ 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);
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 )
+ const TopoDS_Shape& shape = smToCompute->GetSubShape();
+ const TopAbs_ShapeEnum shapeType = shape.ShapeType();
+ if ( !aMesh.HasShapeToMesh() && shapeType == TopAbs_VERTEX )
continue;
// check for preview dimension limitations
- if ( aShapesId && GetShapeDim( aShType ) > (int)aDim )
+ if ( aShapesId && GetShapeDim( shapeType ) > (int)aDim )
{
// clear compute state not to show previous compute errors
// if preview invoked less dimension less than previous
if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
{
-#ifdef WITH_SMESH_CANCEL_COMPUTE
if (_compute_canceled)
return false;
- _sm_current = smToCompute;
-#endif
- smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
-#ifdef WITH_SMESH_CANCEL_COMPUTE
- _sm_current = NULL;
-#endif
+ setCurrentSubMesh( smToCompute );
+ smToCompute->ComputeStateEngine( computeEvent );
+ setCurrentSubMesh( NULL );
}
- // we check all the submeshes here and detect if any of them failed to compute
- if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE)
+ // we check all the sub-meshes here and detect if any of them failed to compute
+ if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE &&
+ ( shapeType != TopAbs_EDGE || !SMESH_Algo::isDegenerated( TopoDS::Edge( shape ))))
ret = false;
else if ( aShapesId )
aShapesId->insert( smToCompute->GetId() );
}
else
{
- // -----------------------------------------------------------------
- // apply algos that DO NOT require Discreteized 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;
+ // ================================================================
+ // Apply algos that do NOT require discreteized boundaries
+ // ("all-dimensional") and do NOT support sub-meshes, starting from
+ // the most complex shapes and collect sub-meshes with algos that
+ // DO support sub-meshes
+ // ================================================================
+
+ list< SMESH_subMesh* > smWithAlgoSupportingSubmeshes[4]; // for each dim
// map to sort sm with same dim algos according to dim of
- // the shape the algo assigned to (issue 0021217)
+ // the shape the algo assigned to (issue 0021217).
+ // Other issues influenced the algo applying order:
+ // 21406, 21556, 21893, 20206
multimap< int, SMESH_subMesh* > shDim2sm;
multimap< int, SMESH_subMesh* >::reverse_iterator shDim2smIt;
TopoDS_Shape algoShape;
- int prevShapeDim = -1;
+ int prevShapeDim = -1, aShapeDim;
smIt = sm->getDependsOnIterator(includeSelf, complexShapeFirst);
while ( smIt->more() )
continue;
const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
- int aShapeDim = GetShapeDim( aSubShape );
+ aShapeDim = GetShapeDim( aSubShape );
if ( aShapeDim < 1 ) break;
// check for preview dimension limitations
if ( aShapesId && aShapeDim > (int)aDim )
continue;
- SMESH_Algo* algo = GetAlgo( aMesh, aSubShape, &algoShape );
+ SMESH_Algo* algo = GetAlgo( smToCompute, &algoShape );
if ( algo && !algo->NeedDiscreteBoundary() )
{
if ( algo->SupportSubmeshes() )
prevShapeDim = aShapeDim;
for ( shDim2smIt = shDim2sm.rbegin(); shDim2smIt != shDim2sm.rend(); ++shDim2smIt )
if ( shDim2smIt->first == globalAlgoDim )
- smWithAlgoSupportingSubmeshes.push_back( shDim2smIt->second );
+ smWithAlgoSupportingSubmeshes[ aShapeDim ].push_back( shDim2smIt->second );
else
- smWithAlgoSupportingSubmeshes.push_front( shDim2smIt->second );
+ smWithAlgoSupportingSubmeshes[ aShapeDim ].push_front( shDim2smIt->second );
shDim2sm.clear();
}
// add smToCompute to shDim2sm map
}
shDim2sm.insert( make_pair( aShapeDim, smToCompute ));
}
- else
+ else // Compute w/o support of sub-meshes
{
-#ifdef WITH_SMESH_CANCEL_COMPUTE
if (_compute_canceled)
return false;
- _sm_current = smToCompute;
-#endif
- smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
-#ifdef WITH_SMESH_CANCEL_COMPUTE
- _sm_current = NULL;
-#endif
+ setCurrentSubMesh( smToCompute );
+ smToCompute->ComputeStateEngine( computeEvent );
+ setCurrentSubMesh( NULL );
if ( aShapesId )
aShapesId->insert( smToCompute->GetId() );
}
// reload sub-meshes from shDim2sm into smWithAlgoSupportingSubmeshes
for ( shDim2smIt = shDim2sm.rbegin(); shDim2smIt != shDim2sm.rend(); ++shDim2smIt )
if ( shDim2smIt->first == globalAlgoDim )
- smWithAlgoSupportingSubmeshes.push_back( shDim2smIt->second );
+ smWithAlgoSupportingSubmeshes[3].push_back( shDim2smIt->second );
else
- smWithAlgoSupportingSubmeshes.push_front( shDim2smIt->second );
+ smWithAlgoSupportingSubmeshes[0].push_front( shDim2smIt->second );
- // ------------------------------------------------------------
- // sort list of submeshes according to mesh order
- // ------------------------------------------------------------
- aMesh.SortByMeshOrder( smWithAlgoSupportingSubmeshes );
+ // ======================================================
+ // Apply all-dimensional algorithms supporing sub-meshes
+ // ======================================================
- // ------------------------------------------------------------
- // compute submeshes under shapes with algos that DO NOT require
- // Discreteized boundaries and DO support submeshes
- // ------------------------------------------------------------
- list< SMESH_subMesh* >::iterator subIt, subEnd;
- subIt = smWithAlgoSupportingSubmeshes.begin();
- subEnd = smWithAlgoSupportingSubmeshes.end();
- // start from lower shapes
- for ( ; subIt != subEnd; ++subIt )
+ std::vector< SMESH_subMesh* > smVec;
+ for ( aShapeDim = 0; aShapeDim < 4; ++aShapeDim )
{
- sm = *subIt;
+ // ------------------------------------------------
+ // sort list of sub-meshes according to mesh order
+ // ------------------------------------------------
+ smVec.assign( smWithAlgoSupportingSubmeshes[ aShapeDim ].begin(),
+ smWithAlgoSupportingSubmeshes[ aShapeDim ].end() );
+ aMesh.SortByMeshOrder( smVec );
+
+ // ------------------------------------------------------------
+ // compute sub-meshes with local uni-dimensional algos under
+ // sub-meshes with all-dimensional algos
+ // ------------------------------------------------------------
+ // start from lower shapes
+ for ( size_t i = 0; i < smVec.size(); ++i )
+ {
+ sm = smVec[i];
- // get a shape the algo is assigned to
- if ( !GetAlgo( aMesh, sm->GetSubShape(), & algoShape ))
- continue; // strange...
+ // get a shape the algo is assigned to
+ if ( !GetAlgo( sm, & algoShape ))
+ continue; // strange...
- // look for more local algos
- smIt = sm->getDependsOnIterator(!includeSelf, !complexShapeFirst);
- while ( smIt->more() )
- {
- SMESH_subMesh* smToCompute = smIt->next();
+ // 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 ( aSubShape.ShapeType() == TopAbs_VERTEX ) continue;
- if ( aShapeDim < 1 ) continue;
+ const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
+ 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 ))
- .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape, aMesh ));
+ // check for preview dimension limitations
+ if ( aShapesId && GetShapeDim( aSubShape.ShapeType() ) > (int)aDim )
+ continue;
- 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
- Compute( aMesh, aSubShape, /*anUpward=*/true, aDim, aShapesId );
+ SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
+ filter
+ .And( SMESH_HypoFilter::IsApplicableTo( aSubShape ))
+ .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape, aMesh ));
+
+ if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( smToCompute, filter, true))
+ {
+ if ( ! subAlgo->NeedDiscreteBoundary() ) continue;
+ SMESH_Hypothesis::Hypothesis_Status status;
+ if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status ))
+ // mesh a lower smToCompute starting from vertices
+ Compute( aMesh, aSubShape, aShapeOnly, /*anUpward=*/true, aDim, aShapesId );
+ }
}
}
- }
- // ----------------------------------------------------------
- // apply the algos that do not require Discreteized boundaries
- // ----------------------------------------------------------
- for ( subIt = smWithAlgoSupportingSubmeshes.begin(); subIt != subEnd; ++subIt )
- {
- sm = *subIt;
- if ( sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
+ // --------------------------------
+ // apply the all-dimensional algos
+ // --------------------------------
+ for ( size_t i = 0; i < smVec.size(); ++i )
{
- const TopAbs_ShapeEnum aShType = sm->GetSubShape().ShapeType();
- // check for preview dimension limitations
- if ( aShapesId && GetShapeDim( aShType ) > (int)aDim )
- continue;
+ sm = smVec[i];
+ if ( sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
+ {
+ const TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType();
+ // check for preview dimension limitations
+ if ( aShapesId && GetShapeDim( shapeType ) > (int)aDim )
+ continue;
-#ifdef WITH_SMESH_CANCEL_COMPUTE
- if (_compute_canceled)
- return false;
- _sm_current = sm;
-#endif
- sm->ComputeStateEngine( SMESH_subMesh::COMPUTE );
-#ifdef WITH_SMESH_CANCEL_COMPUTE
- _sm_current = NULL;
-#endif
- if ( aShapesId )
- aShapesId->insert( sm->GetId() );
+ if (_compute_canceled)
+ return false;
+ setCurrentSubMesh( sm );
+ sm->ComputeStateEngine( computeEvent );
+ setCurrentSubMesh( NULL );
+ if ( aShapesId )
+ aShapesId->insert( sm->GetId() );
+ }
}
- }
+ } // loop on shape dimensions
+
// -----------------------------------------------
// mesh the rest sub-shapes starting from vertices
// -----------------------------------------------
- ret = Compute( aMesh, aShape, /*anUpward=*/true, aDim, aShapesId );
+ ret = Compute( aMesh, aShape, aShapeOnly, /*anUpward=*/true, aDim, aShapesId );
}
- MESSAGE( "VSR - SMESH_Gen::Compute() finished, OK = " << ret);
MEMOSTAT;
SMESHDS_Mesh *myMesh = aMesh.GetMeshDS();
- MESSAGE("*** compactMesh after compute");
+ //MESSAGE("*** compactMesh after compute");
myMesh->compactMesh();
// fix quadratic mesh by bending iternal links near concave boundary
if ( aShape.IsSame( aMesh.GetShapeToMesh() ) &&
- !aShapesId ) // not preview
+ !aShapesId && // not preview
+ ret ) // everything is OK
{
SMESH_MesherHelper aHelper( aMesh );
if ( aHelper.IsQuadraticMesh() != SMESH_MesherHelper::LINEAR )
return ret;
}
-
-#ifdef WITH_SMESH_CANCEL_COMPUTE
//=============================================================================
/*!
* Prepare Compute a mesh
const TopoDS_Shape & aShape)
{
_compute_canceled = false;
- _sm_current = NULL;
+ resetCurrentSubMesh();
}
+
//=============================================================================
/*!
* Cancel Compute a mesh
const TopoDS_Shape & aShape)
{
_compute_canceled = true;
- if(_sm_current)
- {
- _sm_current->ComputeStateEngine( SMESH_subMesh::COMPUTE_CANCELED );
- }
+ if ( const SMESH_subMesh* sm = GetCurrentSubMesh() )
+ {
+ const_cast< SMESH_subMesh* >( sm )->ComputeStateEngine( SMESH_subMesh::COMPUTE_CANCELED );
+ }
+ resetCurrentSubMesh();
+}
+
+//================================================================================
+/*!
+ * \brief Returns a sub-mesh being currently computed
+ */
+//================================================================================
+
+const SMESH_subMesh* SMESH_Gen::GetCurrentSubMesh() const
+{
+ return _sm_current.empty() ? 0 : _sm_current.back();
+}
+
+//================================================================================
+/*!
+ * \brief Sets a sub-mesh being currently computed.
+ *
+ * An algorithm can call Compute() for a sub-shape, hence we keep a stack of sub-meshes
+ */
+//================================================================================
+
+void SMESH_Gen::setCurrentSubMesh(SMESH_subMesh* sm)
+{
+ if ( sm )
+ _sm_current.push_back( sm );
+
+ else if ( !_sm_current.empty() )
+ _sm_current.pop_back();
+}
+
+void SMESH_Gen::resetCurrentSubMesh()
+{
+ _sm_current.clear();
}
-#endif
//=============================================================================
/*!
const bool anUpward,
TSetOfInt* aShapesId)
{
- MESSAGE("SMESH_Gen::Evaluate");
-
bool ret = true;
SMESH_subMesh *sm = aMesh.GetSubMesh(aShape);
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 )
+ const TopAbs_ShapeEnum shapeType = smToCompute->GetSubShape().ShapeType();
+ //if ( !aMesh.HasShapeToMesh() && shapeType == TopAbs_VERTEX )
// continue;
if ( !aMesh.HasShapeToMesh() ) {
- if( aShType == TopAbs_VERTEX || aShType == TopAbs_WIRE ||
- aShType == TopAbs_SHELL )
+ if( shapeType == TopAbs_VERTEX || shapeType == TopAbs_WIRE ||
+ shapeType == TopAbs_SHELL )
continue;
}
else {
// -----------------------------------------------------------------
// apply algos that DO NOT require Discreteized boundaries and DO NOT
- // support submeshes, starting from the most complex shapes
- // and collect submeshes with algos that DO support submeshes
+ // support sub-meshes, starting from the most complex shapes
+ // and collect sub-meshes with algos that DO support sub-meshes
// -----------------------------------------------------------------
list< SMESH_subMesh* > smWithAlgoSupportingSubmeshes;
smIt = sm->getDependsOnIterator(includeSelf, complexShapeFirst);
const int aShapeDim = GetShapeDim( aSubShape );
if ( aShapeDim < 1 ) break;
- SMESH_Algo* algo = GetAlgo( aMesh, aSubShape );
+ SMESH_Algo* algo = GetAlgo( smToCompute );
if ( algo && !algo->NeedDiscreteBoundary() ) {
if ( algo->SupportSubmeshes() ) {
smWithAlgoSupportingSubmeshes.push_front( smToCompute );
// ------------------------------------------------------------
// sort list of meshes according to mesh order
// ------------------------------------------------------------
- aMesh.SortByMeshOrder( smWithAlgoSupportingSubmeshes );
+ std::vector< SMESH_subMesh* > smVec( smWithAlgoSupportingSubmeshes.begin(),
+ smWithAlgoSupportingSubmeshes.end() );
+ aMesh.SortByMeshOrder( smVec );
// ------------------------------------------------------------
- // compute submeshes under shapes with algos that DO NOT require
- // Discreteized boundaries and DO support submeshes
+ // compute sub-meshes under shapes with algos that DO NOT require
+ // Discreteized boundaries and DO support sub-meshes
// ------------------------------------------------------------
- list< SMESH_subMesh* >::iterator subIt, subEnd;
- subIt = smWithAlgoSupportingSubmeshes.begin();
- subEnd = smWithAlgoSupportingSubmeshes.end();
// start from lower shapes
- for ( ; subIt != subEnd; ++subIt ) {
- sm = *subIt;
+ for ( size_t i = 0; i < smVec.size(); ++i )
+ {
+ sm = smVec[i];
// get a shape the algo is assigned to
TopoDS_Shape algoShape;
- if ( !GetAlgo( aMesh, sm->GetSubShape(), & algoShape ))
+ if ( !GetAlgo( sm, & algoShape ))
continue; // strange...
// look for more local algos
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, aMesh ));
- if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) {
+ if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( smToCompute, filter, true ))
+ {
+ if ( ! subAlgo->NeedDiscreteBoundary() ) continue;
SMESH_Hypothesis::Hypothesis_Status status;
if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status ))
// mesh a lower smToCompute starting from vertices
// ----------------------------------------------------------
// apply the algos that do not require Discreteized boundaries
// ----------------------------------------------------------
- for ( subIt = smWithAlgoSupportingSubmeshes.begin(); subIt != subEnd; ++subIt )
+ for ( size_t i = 0; i < smVec.size(); ++i )
{
- sm = *subIt;
+ sm = smVec[i];
sm->Evaluate(aResMap);
if ( aShapesId )
aShapesId->insert( sm->GetId() );
}
else
{
- bool isGlobal = (aMesh.IsMainShape( aSubMesh->GetSubShape() ));
- int dim = algo->GetDim();
+ bool isGlobal = (aMesh.IsMainShape( aSubMesh->GetSubShape() ));
+ int dim = algo->GetDim();
int aMaxGlobIgnoDim = ( aGlobIgnoAlgo ? aGlobIgnoAlgo->GetDim() : -1 );
+ bool isNeededDim = ( aGlobIgnoAlgo ? aGlobIgnoAlgo->NeedLowerHyps( dim ) : false );
- if ( dim < aMaxGlobIgnoDim &&
- ( isGlobal || !aGlobIgnoAlgo->SupportSubmeshes() ))
+ if (( dim < aMaxGlobIgnoDim && !isNeededDim ) &&
+ ( isGlobal || !aGlobIgnoAlgo->SupportSubmeshes() ))
{
// algo is hidden by a global algo
theErrors.push_back( SMESH_Gen::TAlgoStateError() );
theErrors.back().Set( SMESH_Hypothesis::HYP_NOTCONFORM, algo, false );
}
- // sub-algos will be hidden by a local <algo>
+ // sub-algos will be hidden by a local <algo> if <algo> does not support sub-meshes
+ if ( algo->SupportSubmeshes() )
+ algo = 0;
SMESH_subMeshIteratorPtr revItSub =
aSubMesh->getDependsOnIterator( /*includeSelf=*/false, /*complexShapeFirst=*/true);
bool checkConform2 = false;
set<SMESH_subMesh*>& aCheckedMap,
list< SMESH_Gen::TAlgoStateError > & theErrors)
{
- if ( aSubMesh->GetSubShape().ShapeType() == TopAbs_VERTEX ||
- aCheckedMap.count( aSubMesh ))
+ switch ( aSubMesh->GetSubShape().ShapeType() )
+ {
+ case TopAbs_EDGE:
+ case TopAbs_FACE:
+ case TopAbs_SOLID: break; // check this sub-mesh, it can be meshed
+ default:
+ return true; // not meshable sub-mesh
+ }
+ if ( aCheckedMap.count( aSubMesh ))
return true;
- //MESSAGE("=====checkMissing");
-
int ret = true;
SMESH_Algo* algo = 0;
const TopoDS_Shape& theShape,
list< TAlgoStateError > & theErrors)
{
- //MESSAGE("SMESH_Gen::CheckAlgoState");
-
bool ret = true;
bool hasAlgo = false;
// well defined
// ----------------------------------------------------------------
- //MESSAGE( "---info on missing hypothesis and find out if all needed algos are");
-
// find max dim of global algo
int aTopAlgoDim = 0;
for (dim = 3; dim > 0; dim--)
if ( !hasAlgo ) {
ret = false;
- INFOS( "None algorithm attached" );
theErrors.push_back( TAlgoStateError() );
- theErrors.back().Set( SMESH_Hypothesis::HYP_MISSING, 1, true );
+ theErrors.back().Set( SMESH_Hypothesis::HYP_MISSING, theMesh.HasShapeToMesh() ? 1 : 3, true );
}
return ret;
sep = rootDir[pos];
break;
}
-#ifdef WNT
+#ifdef WIN32
if (sep.empty() ) sep = "\\";
#else
if (sep.empty() ) sep = "/";
xmlPath += tolower( pluginSubDir[pos] );
xmlPath += sep + plugin + ".xml";
bool fileOK;
-#ifdef WNT
+#ifdef WIN32
fileOK = (GetFileAttributes(xmlPath.c_str()) != INVALID_FILE_ATTRIBUTES);
#else
fileOK = (access(xmlPath.c_str(), F_OK) == 0);
return xmlPaths;
}
-//=======================================================================
-namespace // Access to type of input and output of an algorithm
-//=======================================================================
-{
- struct AlgoData
- {
- int _dim;
- set<SMDSAbs_GeometryType> _inElemTypes; // acceptable types of input mesh element
- set<SMDSAbs_GeometryType> _outElemTypes; // produced types of mesh elements
-
- bool IsCompatible( const AlgoData& algo2 ) const
- {
- if ( _dim > algo2._dim ) return algo2.IsCompatible( *this );
- // algo2 is of highter dimension
- if ( _outElemTypes.empty() || algo2._inElemTypes.empty() )
- return false;
- bool compatible = true;
- set<SMDSAbs_GeometryType>::const_iterator myOutType = _outElemTypes.begin();
- for ( ; myOutType != _outElemTypes.end() && compatible; ++myOutType )
- compatible = algo2._inElemTypes.count( *myOutType );
- return compatible;
- }
- };
-
- //================================================================================
- /*!
- * \brief Return AlgoData of the algorithm
- */
- //================================================================================
-
- const AlgoData& getAlgoData( const SMESH_Algo* algo )
- {
- static map< string, AlgoData > theDataByName;
- if ( theDataByName.empty() )
- {
- // Read Plugin.xml files
- vector< string > xmlPaths = SMESH_Gen::GetPluginXMLPaths();
- LDOMParser xmlParser;
- for ( size_t iXML = 0; iXML < xmlPaths.size(); ++iXML )
- {
- bool error = xmlParser.parse( xmlPaths[iXML].c_str() );
- if ( error )
- {
- TCollection_AsciiString data;
- INFOS( xmlParser.GetError(data) );
- continue;
- }
- // <algorithm type="Regular_1D"
- // ...
- // input="EDGE"
- // output="QUAD,TRIA">
- //
- LDOM_Document xmlDoc = xmlParser.getDocument();
- LDOM_NodeList algoNodeList = xmlDoc.getElementsByTagName( "algorithm" );
- for ( int i = 0; i < algoNodeList.getLength(); ++i )
- {
- LDOM_Node algoNode = algoNodeList.item( i );
- LDOM_Element& algoElem = (LDOM_Element&) algoNode;
- TCollection_AsciiString algoType = algoElem.getAttribute("type");
- TCollection_AsciiString input = algoElem.getAttribute("input");
- TCollection_AsciiString output = algoElem.getAttribute("output");
- TCollection_AsciiString dim = algoElem.getAttribute("dim");
- if ( algoType.IsEmpty() ) continue;
- AlgoData & data = theDataByName[ algoType.ToCString() ];
- data._dim = dim.IntegerValue();
- for ( int isInput = 0; isInput < 2; ++isInput )
- {
- TCollection_AsciiString& typeStr = isInput ? input : output;
- set<SMDSAbs_GeometryType>& typeSet = isInput ? data._inElemTypes : data._outElemTypes;
- int beg = 1, end;
- while ( beg <= typeStr.Length() )
- {
- while ( beg < typeStr.Length() && !isalpha( typeStr.Value( beg ) ))
- ++beg;
- end = beg;
- while ( end < typeStr.Length() && isalpha( typeStr.Value( end + 1 ) ))
- ++end;
- if ( end > beg )
- {
- TCollection_AsciiString typeName = typeStr.SubString( beg, end );
- if ( typeName == "EDGE" ) typeSet.insert( SMDSGeom_EDGE );
- else if ( typeName == "TRIA" ) typeSet.insert( SMDSGeom_TRIANGLE );
- else if ( typeName == "QUAD" ) typeSet.insert( SMDSGeom_QUADRANGLE );
- }
- beg = end + 1;
- }
- }
- }
- }
- }
- return theDataByName[ algo->GetName() ];
- }
-}
-
//=============================================================================
/*!
* Finds algo to mesh a shape. Optionally returns a shape the found algo is bound to
const TopoDS_Shape & aShape,
TopoDS_Shape* assignedTo)
{
+ return GetAlgo( aMesh.GetSubMesh( aShape ), assignedTo );
+}
+
+//=============================================================================
+/*!
+ * Finds algo to mesh a sub-mesh. Optionally returns a shape the found algo is bound to
+ */
+//=============================================================================
+
+SMESH_Algo *SMESH_Gen::GetAlgo(SMESH_subMesh * aSubMesh,
+ TopoDS_Shape* assignedTo)
+{
+ if ( !aSubMesh ) return 0;
+
+ const TopoDS_Shape & aShape = aSubMesh->GetSubShape();
+ SMESH_Mesh& aMesh = *aSubMesh->GetFather();
+
SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
filter.And( filter.IsApplicableTo( aShape ));
+ typedef SMESH_Algo::Features AlgoData;
+
TopoDS_Shape assignedToShape;
SMESH_Algo* algo =
- (SMESH_Algo*) aMesh.GetHypothesis( aShape, filter, true, &assignedToShape );
+ (SMESH_Algo*) aMesh.GetHypothesis( aSubMesh, filter, true, &assignedToShape );
if ( algo &&
aShape.ShapeType() == TopAbs_FACE &&
filter.AndNot( filter.Is( algo ));
TopoDS_Shape assignedToShape2;
SMESH_Algo* algo2 =
- (SMESH_Algo*) aMesh.GetHypothesis( aShape, filter, true, &assignedToShape2 );
+ (SMESH_Algo*) aMesh.GetHypothesis( aSubMesh, filter, true, &assignedToShape2 );
if ( algo2 && // algo found
!assignedToShape2.IsSame( aMesh.GetShapeToMesh() ) && // algo is local
( SMESH_MesherHelper::GetGroupType( assignedToShape2 ) == // algo of the same level
// check compatibility of algos
if ( algos3D.size() > 1 )
{
- const AlgoData& algoData = getAlgoData( algo );
- const AlgoData& algoData2 = getAlgoData( algo2 );
- const AlgoData& algoData3d0 = getAlgoData( algos3D[0] );
- const AlgoData& algoData3d1 = getAlgoData( algos3D[1] );
+ const AlgoData& algoData = algo->SMESH_Algo::GetFeatures();
+ const AlgoData& algoData2 = algo2->SMESH_Algo::GetFeatures();
+ const AlgoData& algoData3d0 = algos3D[0]->SMESH_Algo::GetFeatures();
+ const AlgoData& algoData3d1 = algos3D[1]->SMESH_Algo::GetFeatures();
if (( algoData2.IsCompatible( algoData3d0 ) &&
algoData2.IsCompatible( algoData3d1 ))
&&