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 "Utils_ExceptHandlers.hxx"
|
||||||
|
|
||||||
#include <TopoDS_Iterator.hxx>
|
#include <TopoDS_Iterator.hxx>
|
||||||
|
#include <LDOMParser.hxx>
|
||||||
|
|
||||||
#include "memoire.h"
|
#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 );
|
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
|
* 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() );
|
SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
|
||||||
filter.And( filter.IsApplicableTo( aShape ));
|
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