mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-11-15 10:08:34 +05:00
0021559: EDF 2175 SMESH: Hexa/Tetra mixed meshes
1) + static std::vector< std::string > GetPluginXMLPaths(); 2) In GetAlgo(), choose a concurrent 2D algorithm whose output is suitable to both different 3D algos on SOLIDs
This commit is contained in:
parent
b2a682e314
commit
7f64a1c94a
@ -43,6 +43,7 @@
|
||||
#include "Utils_ExceptHandlers.hxx"
|
||||
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
#include <LDOMParser.hxx>
|
||||
|
||||
#include "memoire.h"
|
||||
|
||||
@ -896,6 +897,176 @@ bool SMESH_Gen::IsGlobalHypothesis(const SMESH_Hypothesis* theHyp, SMESH_Mesh& a
|
||||
return aMesh.GetHypothesis( aMesh.GetMeshDS()->ShapeToMesh(), filter, false );
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Return paths to xml files of plugins
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
std::vector< std::string > SMESH_Gen::GetPluginXMLPaths()
|
||||
{
|
||||
// Get paths to xml files of plugins
|
||||
vector< string > xmlPaths;
|
||||
string sep;
|
||||
if ( const char* meshersList = getenv("SMESH_MeshersList") )
|
||||
{
|
||||
string meshers = meshersList, plugin;
|
||||
string::size_type from = 0, pos;
|
||||
while ( from < meshers.size() )
|
||||
{
|
||||
// cut off plugin name
|
||||
pos = meshers.find( ':', from );
|
||||
if ( pos != string::npos )
|
||||
plugin = meshers.substr( from, pos-from );
|
||||
else
|
||||
plugin = meshers.substr( from ), pos = meshers.size();
|
||||
from = pos + 1;
|
||||
|
||||
// get PLUGIN_ROOT_DIR path
|
||||
string rootDirVar, pluginSubDir = plugin;
|
||||
if ( plugin == "StdMeshers" )
|
||||
rootDirVar = "SMESH", pluginSubDir = "smesh";
|
||||
else
|
||||
for ( pos = 0; pos < plugin.size(); ++pos )
|
||||
rootDirVar += toupper( plugin[pos] );
|
||||
rootDirVar += "_ROOT_DIR";
|
||||
|
||||
const char* rootDir = getenv( rootDirVar.c_str() );
|
||||
if ( !rootDir || strlen(rootDir) == 0 )
|
||||
{
|
||||
rootDirVar = plugin + "_ROOT_DIR"; // HexoticPLUGIN_ROOT_DIR
|
||||
rootDir = getenv( rootDirVar.c_str() );
|
||||
if ( !rootDir || strlen(rootDir) == 0 ) continue;
|
||||
}
|
||||
|
||||
// get a separator from rootDir
|
||||
for ( pos = strlen( rootDir )-1; pos >= 0 && sep.empty(); --pos )
|
||||
if ( rootDir[pos] == '/' || rootDir[pos] == '\\' )
|
||||
{
|
||||
sep = rootDir[pos];
|
||||
break;
|
||||
}
|
||||
#ifdef WNT
|
||||
if (sep.empty() ) sep = "\\";
|
||||
#else
|
||||
if (sep.empty() ) sep = "/";
|
||||
#endif
|
||||
|
||||
// get a path to resource file
|
||||
string xmlPath = rootDir;
|
||||
if ( xmlPath[ xmlPath.size()-1 ] != sep[0] )
|
||||
xmlPath += sep;
|
||||
xmlPath += "share" + sep + "salome" + sep + "resources" + sep;
|
||||
for ( pos = 0; pos < pluginSubDir.size(); ++pos )
|
||||
xmlPath += tolower( pluginSubDir[pos] );
|
||||
xmlPath += sep + plugin + ".xml";
|
||||
bool fileOK;
|
||||
#ifdef WNT
|
||||
fileOK = (GetFileAttributes(xmlPath.c_str()) != INVALID_FILE_ATTRIBUTES);
|
||||
#else
|
||||
fileOK = (access(xmlPath.c_str(), F_OK) == 0);
|
||||
#endif
|
||||
if ( fileOK )
|
||||
xmlPaths.push_back( xmlPath );
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@ -909,7 +1080,61 @@ SMESH_Algo *SMESH_Gen::GetAlgo(SMESH_Mesh & aMesh,
|
||||
SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
|
||||
filter.And( filter.IsApplicableTo( aShape ));
|
||||
|
||||
return (SMESH_Algo*) aMesh.GetHypothesis( aShape, filter, true, assignedTo );
|
||||
TopoDS_Shape assignedToShape;
|
||||
SMESH_Algo* algo =
|
||||
(SMESH_Algo*) aMesh.GetHypothesis( aShape, filter, true, &assignedToShape );
|
||||
|
||||
if ( algo &&
|
||||
aShape.ShapeType() == TopAbs_FACE &&
|
||||
!aShape.IsSame( assignedToShape ) &&
|
||||
SMESH_MesherHelper::NbAncestors( aShape, aMesh, TopAbs_SOLID ) > 1 )
|
||||
{
|
||||
// Issue 0021559. If there is another 2D algo with different types of output
|
||||
// elements that can be used to mesh aShape, and 3D algos on adjacent SOLIDs
|
||||
// have different types of input elements, we choose a most appropriate 2D algo.
|
||||
|
||||
// try to find a concurrent 2D algo
|
||||
filter.AndNot( filter.Is( algo ));
|
||||
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 ),
|
||||
aMesh.GetSubMesh( assignedToShape )))
|
||||
{
|
||||
// get algos on the adjacent SOLIDs
|
||||
filter.Init( filter.IsAlgo() ).And( filter.HasDim( 3 ));
|
||||
vector< SMESH_Algo* > algos3D;
|
||||
PShapeIteratorPtr solidIt = SMESH_MesherHelper::GetAncestors( aShape, aMesh,
|
||||
TopAbs_SOLID );
|
||||
while ( const TopoDS_Shape* solid = solidIt->next() )
|
||||
if ( SMESH_Algo* algo3D = (SMESH_Algo*) aMesh.GetHypothesis( *solid, filter, true ))
|
||||
{
|
||||
algos3D.push_back( algo3D );
|
||||
filter.AndNot( filter.Is( algo3D ));
|
||||
}
|
||||
// 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] );
|
||||
if (( algoData2.IsCompatible( algoData3d0 ) &&
|
||||
algoData2.IsCompatible( algoData3d1 ))
|
||||
&&
|
||||
!(algoData.IsCompatible( algoData3d0 ) &&
|
||||
algoData.IsCompatible( algoData3d1 )))
|
||||
algo = algo2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( assignedTo && algo )
|
||||
* assignedTo = assignedToShape;
|
||||
|
||||
return algo;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
Loading…
Reference in New Issue
Block a user