#include "Utils_ExceptHandlers.hxx"
#include <TopoDS_Iterator.hxx>
-#include <LDOMParser.hxx>
#include "memoire.h"
+#ifdef WNT
+ #include <windows.h>
+#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
+ 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);
+ _compute_canceled = false;
+ _sm_current = NULL;
+ //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;
+ }
}
//=============================================================================
const int globalAlgoDim = 100;
SMESH_subMeshIteratorPtr smIt;
+ SMESH_subMesh::compute_event computeEvent;
+ if ( !anUpward && aShape.IsSame( aMesh.GetShapeToMesh() ))
+ computeEvent = SMESH_subMesh::COMPUTE;
+ else
+ computeEvent = SMESH_subMesh::COMPUTE_SUBMESH;
if ( anUpward ) // is called from below code here
{
// check for preview dimension limitations
if ( aShapesId && GetShapeDim( aShType ) > (int)aDim )
{
- // clear compute state to not show previous compute errors
+ // clear compute state not to 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)
{
-#ifdef WITH_SMESH_CANCEL_COMPUTE
if (_compute_canceled)
return false;
_sm_current = smToCompute;
-#endif
- smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
-#ifdef WITH_SMESH_CANCEL_COMPUTE
+ smToCompute->ComputeStateEngine( computeEvent );
_sm_current = NULL;
-#endif
}
// we check all the submeshes here and detect if any of them failed to compute
}
else
{
-#ifdef WITH_SMESH_CANCEL_COMPUTE
if (_compute_canceled)
return false;
_sm_current = smToCompute;
-#endif
- smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
-#ifdef WITH_SMESH_CANCEL_COMPUTE
+ smToCompute->ComputeStateEngine( computeEvent );
_sm_current = NULL;
-#endif
if ( aShapesId )
aShapesId->insert( smToCompute->GetId() );
}
.And( SMESH_HypoFilter::IsMoreLocalThan( algoShape, aMesh ));
if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) {
+ if ( ! subAlgo->NeedDiscreteBoundary() ) continue;
SMESH_Hypothesis::Hypothesis_Status status;
if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status ))
// mesh a lower smToCompute starting from vertices
if ( aShapesId && GetShapeDim( aShType ) > (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->ComputeStateEngine( computeEvent );
_sm_current = NULL;
-#endif
if ( aShapesId )
aShapesId->insert( sm->GetId() );
}
MEMOSTAT;
SMESHDS_Mesh *myMesh = aMesh.GetMeshDS();
- myMesh->adjustStructure();
MESSAGE("*** compactMesh after compute");
myMesh->compactMesh();
- //myMesh->adjustStructure();
- list<int> listind = myMesh->SubMeshIndices();
- list<int>::iterator it = listind.begin();
- int total = 0;
- for(; it != listind.end(); ++it)
- {
- ::SMESHDS_SubMesh *subMesh = myMesh->MeshElements(*it);
- total += subMesh->getSize();
- }
- MESSAGE("total elements and nodes in submesh sets:" << total);
- MESSAGE("Number of node objects " << SMDS_MeshNode::nbNodes);
- MESSAGE("Number of cell objects " << SMDS_MeshCell::nbCells);
- //myMesh->dumpGrid();
- //aMesh.GetMeshDS()->Modified();
// 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 )
- aHelper.FixQuadraticElements();
+ {
+ aHelper.FixQuadraticElements( sm->GetComputeError() );
+ }
}
return ret;
}
.And( SMESH_HypoFilter::IsMoreLocalThan( algoShape, aMesh ));
if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) {
+ if ( ! subAlgo->NeedDiscreteBoundary() ) continue;
SMESH_Hypothesis::Hypothesis_Status status;
if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status ))
// mesh a lower smToCompute starting from vertices
if ( aLocIgnoAlgo ) // algo is hidden by a local algo of upper dim
{
+ theErrors.push_back( SMESH_Gen::TAlgoStateError() );
+ theErrors.back().Set( SMESH_Hypothesis::HYP_HIDDEN_ALGO, algo, false );
INFOS( "Local <" << algo->GetName() << "> is hidden by local <"
<< aLocIgnoAlgo->GetName() << ">");
}
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 )
+ 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_HIDDEN_ALGO, algo, true );
INFOS( ( isGlobal ? "Global" : "Local" )
<< " <" << algo->GetName() << "> is hidden by global <"
<< aGlobIgnoAlgo->GetName() << ">");
set<SMESH_subMesh*>& aCheckedMap,
list< SMESH_Gen::TAlgoStateError > & theErrors)
{
- if ( aSubMesh->GetSubShape().ShapeType() == TopAbs_VERTEX)
+ switch ( aSubMesh->GetSubShape().ShapeType() )
+ {
+ case TopAbs_EDGE:
+ case TopAbs_FACE:
+ case TopAbs_SOLID: break; // check this submesh, it can be meshed
+ default:
+ return true; // not meshable submesh
+ }
+ if ( aCheckedMap.count( aSubMesh ))
return true;
//MESSAGE("=====checkMissing");
}
case SMESH_subMesh::MISSING_HYP: {
// notify if an algo missing hyp is attached to aSubMesh
- algo = aGen->GetAlgo( aMesh, aSubMesh->GetSubShape() );
+ algo = aSubMesh->GetAlgo();
ASSERT( algo );
bool IsGlobalHypothesis = aGen->IsGlobalHypothesis( algo, aMesh );
if (!IsGlobalHypothesis || !globalChecked[ algo->GetDim() ])
break;
}
case SMESH_subMesh::HYP_OK:
- algo = aGen->GetAlgo( aMesh, aSubMesh->GetSubShape() );
+ algo = aSubMesh->GetAlgo();
ret = true;
+ if (!algo->NeedDiscreteBoundary())
+ {
+ SMESH_subMeshIteratorPtr itsub = aSubMesh->getDependsOnIterator( /*includeSelf=*/false,
+ /*complexShapeFirst=*/false);
+ while ( itsub->more() )
+ aCheckedMap.insert( itsub->next() );
+ }
break;
default: ASSERT(0);
}
{
bool checkNoAlgo2 = ( algo->NeedDiscreteBoundary() );
SMESH_subMeshIteratorPtr itsub = aSubMesh->getDependsOnIterator( /*includeSelf=*/false,
- /*complexShapeFirst=*/false);
+ /*complexShapeFirst=*/true);
while ( itsub->more() )
{
// sub-meshes should not be checked further more
SMESH_subMesh* sm = itsub->next();
- aCheckedMap.insert( sm );
if (isTopLocalAlgo)
{
checkNoAlgo2 = false;
}
}
+ aCheckedMap.insert( sm );
}
}
return ret;
bool ret = true;
bool hasAlgo = false;
- SMESH_subMesh* sm = theMesh.GetSubMesh(theShape);
+ SMESH_subMesh* sm = theMesh.GetSubMesh(theShape);
const SMESHDS_Mesh* meshDS = theMesh.GetMeshDS();
- TopoDS_Shape mainShape = meshDS->ShapeToMesh();
+ TopoDS_Shape mainShape = meshDS->ShapeToMesh();
// -----------------
// get global algos
for (dim = 3; dim > 0; dim--)
{
if (aGlobAlgoArr[ dim ] &&
- !aGlobAlgoArr[ dim ]->NeedDiscreteBoundary())
+ !aGlobAlgoArr[ dim ]->NeedDiscreteBoundary() /*&&
+ !aGlobAlgoArr[ dim ]->SupportSubmeshes()*/ )
{
aGlobIgnoAlgo = aGlobAlgoArr[ dim ];
break;
if ( smToCheck->GetSubShape().ShapeType() == TopAbs_VERTEX)
break;
- if ( aCheckedSubs.insert( smToCheck ).second ) // not yet checked
- if (!checkMissing (this, theMesh, smToCheck, aTopAlgoDim,
- globalChecked, checkNoAlgo, aCheckedSubs, theErrors))
- {
- ret = false;
- if (smToCheck->GetAlgoState() == SMESH_subMesh::NO_ALGO )
- checkNoAlgo = false;
- }
+ if (!checkMissing (this, theMesh, smToCheck, aTopAlgoDim,
+ globalChecked, checkNoAlgo, aCheckedSubs, theErrors))
+ {
+ ret = false;
+ if (smToCheck->GetAlgoState() == SMESH_subMesh::NO_ALGO )
+ checkNoAlgo = false;
+ }
}
if ( !hasAlgo ) {
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 i = 0; i < xmlPaths.size(); ++i )
- {
- bool error = xmlParser.parse( xmlPaths[i].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");
- 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
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 );
TopoDS_Shape assignedToShape2;
SMESH_Algo* algo2 =
(SMESH_Algo*) aMesh.GetHypothesis( aShape, filter, true, &assignedToShape2 );
- if ( algo2 &&
- assignedToShape2.ShapeType() == assignedToShape.ShapeType() &&
- aMesh.IsOrderOK( aMesh.GetSubMesh( assignedToShape2 ),
+ if ( algo2 && // algo found
+ !assignedToShape2.IsSame( aMesh.GetShapeToMesh() ) && // algo is local
+ ( SMESH_MesherHelper::GetGroupType( assignedToShape2 ) == // algo of the same level
+ SMESH_MesherHelper::GetGroupType( assignedToShape )) &&
+ aMesh.IsOrderOK( aMesh.GetSubMesh( assignedToShape2 ), // no forced order
aMesh.GetSubMesh( assignedToShape )))
{
// get algos on the adjacent SOLIDs
if ( SMESH_Algo* algo3D = (SMESH_Algo*) aMesh.GetHypothesis( *solid, filter, true ))
{
algos3D.push_back( algo3D );
- filter.AndNot( filter.Is( algo3D ));
+ filter.AndNot( filter.HasName( algo3D->GetName() ));
}
// 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 ))
&&