mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-02-04 21:44:17 +05:00
[bos #38521][EDF] Split Polyhedron with more than one volume.
Improve comment and add bother volumes to mesh body. . Change typo of counters to avoid compilation warnings.
This commit is contained in:
parent
b363bece45
commit
1dab7a05bb
@ -938,6 +938,7 @@ namespace
|
|||||||
TGeomID _solidID;
|
TGeomID _solidID;
|
||||||
double _size;
|
double _size;
|
||||||
const SMDS_MeshElement* _volume; // new volume
|
const SMDS_MeshElement* _volume; // new volume
|
||||||
|
std::vector<const SMDS_MeshElement*> _brotherVolume; // produced due to poly split
|
||||||
|
|
||||||
vector< SMESH_Block::TShapeID > _names; // name of side a polygon originates from
|
vector< SMESH_Block::TShapeID > _names; // name of side a polygon originates from
|
||||||
|
|
||||||
@ -1069,6 +1070,10 @@ namespace
|
|||||||
bool isInHole() const;
|
bool isInHole() const;
|
||||||
bool hasStrangeEdge() const;
|
bool hasStrangeEdge() const;
|
||||||
bool checkPolyhedronSize( bool isCutByInternalFace, double & volSize ) const;
|
bool checkPolyhedronSize( bool isCutByInternalFace, double & volSize ) const;
|
||||||
|
int checkPolyhedronValidity( _volumeDef* volDef, std::vector<std::vector<int>>& splitQuantities,
|
||||||
|
std::vector<std::vector<const SMDS_MeshNode*>>& splitNodes );
|
||||||
|
const SMDS_MeshElement* addPolyhedronToMesh( _volumeDef* volDef, SMESH_MesherHelper& helper, const std::vector<const SMDS_MeshNode*>& nodes,
|
||||||
|
const std::vector<int>& quantities );
|
||||||
bool addHexa ();
|
bool addHexa ();
|
||||||
bool addTetra();
|
bool addTetra();
|
||||||
bool addPenta();
|
bool addPenta();
|
||||||
@ -3556,7 +3561,6 @@ namespace
|
|||||||
_volumeDefs._nodes.clear();
|
_volumeDefs._nodes.clear();
|
||||||
_volumeDefs._quantities.clear();
|
_volumeDefs._quantities.clear();
|
||||||
_volumeDefs._names.clear();
|
_volumeDefs._names.clear();
|
||||||
|
|
||||||
// create a classic cell if possible
|
// create a classic cell if possible
|
||||||
|
|
||||||
int nbPolygons = 0;
|
int nbPolygons = 0;
|
||||||
@ -4851,26 +4855,27 @@ namespace
|
|||||||
} // loop to get nodes
|
} // loop to get nodes
|
||||||
|
|
||||||
const SMDS_MeshElement* v = 0;
|
const SMDS_MeshElement* v = 0;
|
||||||
|
|
||||||
if ( !volDef->_quantities.empty() )
|
if ( !volDef->_quantities.empty() )
|
||||||
{
|
{
|
||||||
v = helper.AddPolyhedralVolume( nodes, volDef->_quantities );
|
// split polyhedrons of with disjoint volumes
|
||||||
volDef->_size = SMDS_VolumeTool( v ).GetSize();
|
std::vector<std::vector<int>> splitQuantities;
|
||||||
if ( volDef->_size < 0 ) // invalid polyhedron
|
std::vector<std::vector< const SMDS_MeshNode* > > splitNodes;
|
||||||
|
if ( checkPolyhedronValidity( volDef, splitQuantities, splitNodes ) == 1 )
|
||||||
{
|
{
|
||||||
if ( ! SMESH_MeshEditor( helper.GetMesh() ).Reorient( v ) || // try to fix
|
v = addPolyhedronToMesh( volDef, helper, nodes, volDef->_quantities );
|
||||||
SMDS_VolumeTool( v ).GetSize() < 0 )
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int counter = -1;
|
||||||
|
for (size_t id = 0; id < splitQuantities.size(); id++)
|
||||||
{
|
{
|
||||||
helper.GetMeshDS()->RemoveFreeElement( v, /*sm=*/nullptr, /*fromGroups=*/false );
|
v = addPolyhedronToMesh( volDef, helper, splitNodes[ id ], splitQuantities[ id ] );
|
||||||
v = nullptr;
|
if ( id < splitQuantities.size()-1 )
|
||||||
//_hasTooSmall = true;
|
volDef->_brotherVolume.push_back( v );
|
||||||
|
counter++;
|
||||||
if (SALOME::VerbosityActivated())
|
|
||||||
{
|
|
||||||
std::cout << "Remove INVALID polyhedron, _cellID = " << _cellID
|
|
||||||
<< " ijk = ( " << _i << " " << _j << " " << _k << " ) "
|
|
||||||
<< " solid " << volDef->_solidID << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
nbAdded += counter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -4928,6 +4933,10 @@ namespace
|
|||||||
if ( volDef->_volume )
|
if ( volDef->_volume )
|
||||||
{
|
{
|
||||||
helper.GetMeshDS()->SetMeshElementOnShape( volDef->_volume, volDef->_solidID );
|
helper.GetMeshDS()->SetMeshElementOnShape( volDef->_volume, volDef->_solidID );
|
||||||
|
for (auto broVol : volDef->_brotherVolume )
|
||||||
|
{
|
||||||
|
helper.GetMeshDS()->SetMeshElementOnShape( broVol, volDef->_solidID );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5077,6 +5086,159 @@ namespace
|
|||||||
|
|
||||||
return volume > initVolume / _grid->_sizeThreshold;
|
return volume > initVolume / _grid->_sizeThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Check that all faces in polyhedron are connected so a unique volume is defined.
|
||||||
|
* We test that it is possible to go from any node to all nodes in the polyhedron.
|
||||||
|
* The set of nodes that can be visit within then defines a unique element.
|
||||||
|
* In case more than one polyhedron is detected. The function return the set of quantities and nodes defining separates elements.
|
||||||
|
* Reference to issue #bos[38521][EDF] Generate polyhedron with separate volume.
|
||||||
|
*/
|
||||||
|
int Hexahedron::checkPolyhedronValidity( _volumeDef* volDef, std::vector<std::vector<int>>& splitQuantities,
|
||||||
|
std::vector<std::vector<const SMDS_MeshNode*>>& splitNodes )
|
||||||
|
{
|
||||||
|
int mySet = 1;
|
||||||
|
std::map<int,int> numberOfSets; // define set id with the number of faces associated!
|
||||||
|
if ( !volDef->_quantities.empty() )
|
||||||
|
{
|
||||||
|
auto connectivity = volDef->_quantities;
|
||||||
|
int accum = 0;
|
||||||
|
std::vector<bool> allFaces( connectivity.size(), false );
|
||||||
|
std::set<int> elementSet;
|
||||||
|
allFaces[ 0 ] = true; // the first node below to the first face
|
||||||
|
size_t connectedFaces = 1;
|
||||||
|
// Start filling the set with the nodes of the first face
|
||||||
|
splitQuantities.push_back( { connectivity[ 0 ] } );
|
||||||
|
splitNodes.push_back( { volDef->_nodes[ 0 ].Node() } );
|
||||||
|
elementSet.insert( volDef->_nodes[ 0 ].Node()->GetID() );
|
||||||
|
for (int n = 1; n < connectivity[ 0 ]; n++)
|
||||||
|
{
|
||||||
|
elementSet.insert( volDef->_nodes[ n ].Node()->GetID() );
|
||||||
|
splitNodes.back().push_back( volDef->_nodes[ n ].Node() );
|
||||||
|
}
|
||||||
|
|
||||||
|
numberOfSets.insert( std::pair<int,int>(mySet,1) );
|
||||||
|
while ( connectedFaces != allFaces.size() )
|
||||||
|
{
|
||||||
|
for (size_t innerId = 1; innerId < connectivity.size(); innerId++)
|
||||||
|
{
|
||||||
|
if ( innerId == 1 )
|
||||||
|
accum = connectivity[ 0 ];
|
||||||
|
|
||||||
|
if ( !allFaces[ innerId ] )
|
||||||
|
{
|
||||||
|
int faceCounter = 0;
|
||||||
|
for (int n = 0; n < connectivity[ innerId ]; n++)
|
||||||
|
{
|
||||||
|
int nodeId = volDef->_nodes[ accum + n ].Node()->GetID();
|
||||||
|
if ( elementSet.count( nodeId ) != 0 )
|
||||||
|
faceCounter++;
|
||||||
|
}
|
||||||
|
if ( faceCounter >= 2 ) // found coincidences nodes
|
||||||
|
{
|
||||||
|
for (int n = 0; n < connectivity[ innerId ]; n++)
|
||||||
|
{
|
||||||
|
int nodeId = volDef->_nodes[ accum + n ].Node()->GetID();
|
||||||
|
// insert new nodes so other faces can be identified as belowing to the element
|
||||||
|
splitNodes.back().push_back( volDef->_nodes[ accum + n ].Node() );
|
||||||
|
elementSet.insert( nodeId );
|
||||||
|
}
|
||||||
|
allFaces[ innerId ] = true;
|
||||||
|
splitQuantities.back().push_back( connectivity[ innerId ] );
|
||||||
|
numberOfSets[ mySet ]++;
|
||||||
|
connectedFaces++;
|
||||||
|
innerId = 0; // to restart searching!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
accum += connectivity[ innerId ];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( connectedFaces != allFaces.size() )
|
||||||
|
{
|
||||||
|
// empty the set, and fill it with nodes of a unvisited face!
|
||||||
|
elementSet.clear();
|
||||||
|
accum = connectivity[ 0 ];
|
||||||
|
for (size_t faceId = 1; faceId < connectivity.size(); faceId++)
|
||||||
|
{
|
||||||
|
if ( !allFaces[ faceId ] )
|
||||||
|
{
|
||||||
|
splitNodes.push_back( { volDef->_nodes[ accum ].Node() } );
|
||||||
|
elementSet.insert( volDef->_nodes[ accum ].Node()->GetID() );
|
||||||
|
for (int n = 1; n < connectivity[ faceId ]; n++)
|
||||||
|
{
|
||||||
|
elementSet.insert( volDef->_nodes[ accum + n ].Node()->GetID() );
|
||||||
|
splitNodes.back().push_back( volDef->_nodes[ accum + n ].Node() );
|
||||||
|
}
|
||||||
|
|
||||||
|
splitQuantities.push_back( { connectivity[ faceId ] } );
|
||||||
|
allFaces[ faceId ] = true;
|
||||||
|
connectedFaces++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
accum += connectivity[ faceId ];
|
||||||
|
}
|
||||||
|
mySet++;
|
||||||
|
numberOfSets.insert( std::pair<int,int>(mySet,1) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( numberOfSets.size() > 1 )
|
||||||
|
{
|
||||||
|
bool allMoreThan2Faces = true;
|
||||||
|
for( auto k : numberOfSets )
|
||||||
|
{
|
||||||
|
if ( k.second <= 2 )
|
||||||
|
allMoreThan2Faces &= false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( allMoreThan2Faces )
|
||||||
|
{
|
||||||
|
// The separate objects are suspect to be closed
|
||||||
|
return numberOfSets.size();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Have to index the last face nodes to the final set
|
||||||
|
// contrary case return as it were a valid polyhedron for backward compatibility
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return numberOfSets.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief add original or separated polyhedrons to the mesh
|
||||||
|
*/
|
||||||
|
const SMDS_MeshElement* Hexahedron::addPolyhedronToMesh( _volumeDef* volDef, SMESH_MesherHelper& helper, const std::vector<const SMDS_MeshNode*>& nodes,
|
||||||
|
const std::vector<int>& quantities )
|
||||||
|
{
|
||||||
|
const SMDS_MeshElement* v = helper.AddPolyhedralVolume( nodes, quantities );
|
||||||
|
|
||||||
|
volDef->_size = SMDS_VolumeTool( v ).GetSize();
|
||||||
|
if ( volDef->_size < 0 ) // invalid polyhedron
|
||||||
|
{
|
||||||
|
if ( ! SMESH_MeshEditor( helper.GetMesh() ).Reorient( v ) || // try to fix
|
||||||
|
SMDS_VolumeTool( v ).GetSize() < 0 )
|
||||||
|
{
|
||||||
|
helper.GetMeshDS()->RemoveFreeElement( v, /*sm=*/nullptr, /*fromGroups=*/false );
|
||||||
|
v = nullptr;
|
||||||
|
//_hasTooSmall = true;
|
||||||
|
|
||||||
|
if (SALOME::VerbosityActivated())
|
||||||
|
{
|
||||||
|
std::cout << "Remove INVALID polyhedron, _cellID = " << _cellID
|
||||||
|
<< " ijk = ( " << _i << " " << _j << " " << _k << " ) "
|
||||||
|
<< " solid " << volDef->_solidID << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Tries to create a hexahedron
|
* \brief Tries to create a hexahedron
|
||||||
@ -5817,6 +5979,14 @@ namespace
|
|||||||
for ( size_t iN = 0; iN < volDef->_nodes.size(); ++iN )
|
for ( size_t iN = 0; iN < volDef->_nodes.size(); ++iN )
|
||||||
volDef->_nodes[iN].Node()->setIsMarked( false );
|
volDef->_nodes[iN].Node()->setIsMarked( false );
|
||||||
}
|
}
|
||||||
|
if ( volDef->_brotherVolume.size() > 0 )
|
||||||
|
{
|
||||||
|
for (auto _bro : volDef->_brotherVolume )
|
||||||
|
{
|
||||||
|
_bro->setIsMarked( true );
|
||||||
|
boundaryElems.push_back( _bro );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user