mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-11-15 10:08:34 +05:00
0020889: EDF 1433 SMESH: SplitHexaToTetra: add the 24 tetras mode
* Add HEXA_TO_24 splitting mode * Fix ConvertToQuadratic() to avoid disappearance of poly elements
This commit is contained in:
parent
d246fa304c
commit
679fca4c8a
@ -1242,6 +1242,7 @@ namespace
|
|||||||
const int* _connectivity; //!< foursomes of tetra connectivy finished by -1
|
const int* _connectivity; //!< foursomes of tetra connectivy finished by -1
|
||||||
bool _baryNode; //!< additional node is to be created at cell barycenter
|
bool _baryNode; //!< additional node is to be created at cell barycenter
|
||||||
bool _ownConn; //!< to delete _connectivity in destructor
|
bool _ownConn; //!< to delete _connectivity in destructor
|
||||||
|
map<int, const SMDS_MeshNode*> _faceBaryNode; //!< map face index to node at BC of face
|
||||||
|
|
||||||
TSplitMethod( int nbTet=0, const int* conn=0, bool addNode=false)
|
TSplitMethod( int nbTet=0, const int* conn=0, bool addNode=false)
|
||||||
: _nbTetra(nbTet), _connectivity(conn), _baryNode(addNode), _ownConn(false) {}
|
: _nbTetra(nbTet), _connectivity(conn), _baryNode(addNode), _ownConn(false) {}
|
||||||
@ -1267,7 +1268,12 @@ namespace
|
|||||||
|
|
||||||
TSplitMethod getSplitMethod( SMDS_VolumeTool& vol, const int theMethodFlags)
|
TSplitMethod getSplitMethod( SMDS_VolumeTool& vol, const int theMethodFlags)
|
||||||
{
|
{
|
||||||
int iQ = vol.Element()->IsQuadratic() ? 2 : 1;
|
const int iQ = vol.Element()->IsQuadratic() ? 2 : 1;
|
||||||
|
|
||||||
|
// at HEXA_TO_24 method, each face of volume is split into triangles each based on
|
||||||
|
// an edge and a face barycenter; tertaherdons are based on triangles and
|
||||||
|
// a volume barycenter
|
||||||
|
const bool is24TetMode = ( theMethodFlags == SMESH_MeshEditor::HEXA_TO_24 );
|
||||||
|
|
||||||
// Find out how adjacent volumes are split
|
// Find out how adjacent volumes are split
|
||||||
|
|
||||||
@ -1276,7 +1282,7 @@ namespace
|
|||||||
for ( int iF = 0; iF < vol.NbFaces(); ++iF )
|
for ( int iF = 0; iF < vol.NbFaces(); ++iF )
|
||||||
{
|
{
|
||||||
int nbNodes = vol.NbFaceNodes( iF ) / iQ;
|
int nbNodes = vol.NbFaceNodes( iF ) / iQ;
|
||||||
maxTetConnSize += 4 * ( nbNodes - 2 );
|
maxTetConnSize += 4 * ( nbNodes - (is24TetMode ? 0 : 2));
|
||||||
if ( nbNodes < 4 ) continue;
|
if ( nbNodes < 4 ) continue;
|
||||||
|
|
||||||
list< TTriangleFacet >& triaSplits = triaSplitsByFace[ iF ];
|
list< TTriangleFacet >& triaSplits = triaSplitsByFace[ iF ];
|
||||||
@ -1314,7 +1320,7 @@ namespace
|
|||||||
// Among variants of split method select one compliant with adjacent volumes
|
// Among variants of split method select one compliant with adjacent volumes
|
||||||
|
|
||||||
TSplitMethod method;
|
TSplitMethod method;
|
||||||
if ( !vol.Element()->IsPoly() )
|
if ( !vol.Element()->IsPoly() && !is24TetMode )
|
||||||
{
|
{
|
||||||
int nbVariants = 2, nbTet = 0;
|
int nbVariants = 2, nbTet = 0;
|
||||||
const int** connVariants = 0;
|
const int** connVariants = 0;
|
||||||
@ -1322,7 +1328,7 @@ namespace
|
|||||||
{
|
{
|
||||||
case SMDSEntity_Hexa:
|
case SMDSEntity_Hexa:
|
||||||
case SMDSEntity_Quad_Hexa:
|
case SMDSEntity_Quad_Hexa:
|
||||||
if ( theMethodFlags & SMESH_MeshEditor::HEXA_TO_5 )
|
if ( theMethodFlags == SMESH_MeshEditor::HEXA_TO_5 )
|
||||||
connVariants = theHexTo5, nbTet = 5;
|
connVariants = theHexTo5, nbTet = 5;
|
||||||
else
|
else
|
||||||
connVariants = theHexTo6, nbTet = 6, nbVariants = 4;
|
connVariants = theHexTo6, nbTet = 6, nbVariants = 4;
|
||||||
@ -1386,7 +1392,7 @@ namespace
|
|||||||
facet->contains( nInd[ iQ * ((iCommon+2)%nbNodes) ]))
|
facet->contains( nInd[ iQ * ((iCommon+2)%nbNodes) ]))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if ( nbNodes > 3 )
|
else if ( nbNodes > 3 && !is24TetMode )
|
||||||
{
|
{
|
||||||
// find the best method of splitting into triangles by aspect ratio
|
// find the best method of splitting into triangles by aspect ratio
|
||||||
SMESH::Controls::NumericalFunctorPtr aspectRatio( new SMESH::Controls::AspectRatio);
|
SMESH::Controls::NumericalFunctorPtr aspectRatio( new SMESH::Controls::AspectRatio);
|
||||||
@ -1407,8 +1413,26 @@ namespace
|
|||||||
}
|
}
|
||||||
if ( iCommon >= nbNodes )
|
if ( iCommon >= nbNodes )
|
||||||
iCommon = 0; // something wrong
|
iCommon = 0; // something wrong
|
||||||
// fill connectivity of tetra
|
|
||||||
|
// fill connectivity of tetrahedra based on a current face
|
||||||
int nbTet = nbNodes - 2;
|
int nbTet = nbNodes - 2;
|
||||||
|
if ( is24TetMode && nbNodes > 3 && triaSplits.empty())
|
||||||
|
{
|
||||||
|
method._faceBaryNode.insert( make_pair( iF, (const SMDS_MeshNode*)0 ));
|
||||||
|
int faceBaryCenInd = baryCenInd + method._faceBaryNode.size();
|
||||||
|
nbTet = nbNodes;
|
||||||
|
for ( int i = 0; i < nbTet; ++i )
|
||||||
|
{
|
||||||
|
int i1 = i, i2 = (i+1) % nbNodes;
|
||||||
|
if ( !vol.IsFaceExternal( iF )) swap( i1, i2 );
|
||||||
|
connectivity[ connSize++ ] = nInd[ iQ * i1 ];
|
||||||
|
connectivity[ connSize++ ] = nInd[ iQ * i2 ];
|
||||||
|
connectivity[ connSize++ ] = faceBaryCenInd;
|
||||||
|
connectivity[ connSize++ ] = baryCenInd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
for ( int i = 0; i < nbTet; ++i )
|
for ( int i = 0; i < nbTet; ++i )
|
||||||
{
|
{
|
||||||
int i1 = (iCommon+1+i) % nbNodes, i2 = (iCommon+2+i) % nbNodes;
|
int i1 = (iCommon+1+i) % nbNodes, i2 = (iCommon+2+i) % nbNodes;
|
||||||
@ -1417,9 +1441,10 @@ namespace
|
|||||||
connectivity[ connSize++ ] = nInd[ iQ * i1 ];
|
connectivity[ connSize++ ] = nInd[ iQ * i1 ];
|
||||||
connectivity[ connSize++ ] = nInd[ iQ * i2 ];
|
connectivity[ connSize++ ] = nInd[ iQ * i2 ];
|
||||||
connectivity[ connSize++ ] = baryCenInd;
|
connectivity[ connSize++ ] = baryCenInd;
|
||||||
++method._nbTetra;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
method._nbTetra += nbTet;
|
||||||
|
}
|
||||||
connectivity[ connSize++ ] = -1;
|
connectivity[ connSize++ ] = -1;
|
||||||
}
|
}
|
||||||
return method;
|
return method;
|
||||||
@ -1453,6 +1478,29 @@ namespace
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
/*!
|
||||||
|
* \brief A key of a face of volume
|
||||||
|
*/
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
struct TVolumeFaceKey: pair< int, pair< int, int> >
|
||||||
|
{
|
||||||
|
TVolumeFaceKey( SMDS_VolumeTool& vol, int iF )
|
||||||
|
{
|
||||||
|
TIDSortedNodeSet sortedNodes;
|
||||||
|
const int iQ = vol.Element()->IsQuadratic() ? 2 : 1;
|
||||||
|
int nbNodes = vol.NbFaceNodes( iF );
|
||||||
|
const SMDS_MeshNode** fNodes = vol.GetFaceNodes( iF );
|
||||||
|
for ( int i = 0; i < nbNodes; i += iQ )
|
||||||
|
sortedNodes.insert( fNodes[i] );
|
||||||
|
TIDSortedNodeSet::iterator n = sortedNodes.begin();
|
||||||
|
first = (*(n++))->GetID();
|
||||||
|
second.first = (*(n++))->GetID();
|
||||||
|
second.second = (*(n++))->GetID();
|
||||||
|
}
|
||||||
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@ -1475,6 +1523,10 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems,
|
|||||||
|
|
||||||
SMESH_SequenceOfElemPtr newNodes, newElems;
|
SMESH_SequenceOfElemPtr newNodes, newElems;
|
||||||
|
|
||||||
|
// map face of volume to it's baricenrtic node
|
||||||
|
map< TVolumeFaceKey, const SMDS_MeshNode* > volFace2BaryNode;
|
||||||
|
double bc[3];
|
||||||
|
|
||||||
TIDSortedElemSet::const_iterator elem = theElems.begin();
|
TIDSortedElemSet::const_iterator elem = theElems.begin();
|
||||||
for ( ; elem != theElems.end(); ++elem )
|
for ( ; elem != theElems.end(); ++elem )
|
||||||
{
|
{
|
||||||
@ -1487,7 +1539,7 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems,
|
|||||||
TSplitMethod splitMethod = getSplitMethod( volTool, theMethodFlags );
|
TSplitMethod splitMethod = getSplitMethod( volTool, theMethodFlags );
|
||||||
if ( splitMethod._nbTetra < 1 ) continue;
|
if ( splitMethod._nbTetra < 1 ) continue;
|
||||||
|
|
||||||
// find submesh to add new tetras in
|
// find submesh to add new tetras to
|
||||||
if ( !subMesh || !subMesh->Contains( *elem ))
|
if ( !subMesh || !subMesh->Contains( *elem ))
|
||||||
{
|
{
|
||||||
int shapeID = FindShape( *elem );
|
int shapeID = FindShape( *elem );
|
||||||
@ -1516,12 +1568,28 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems,
|
|||||||
if ( splitMethod._baryNode )
|
if ( splitMethod._baryNode )
|
||||||
{
|
{
|
||||||
// make a node at barycenter
|
// make a node at barycenter
|
||||||
gp_XYZ gc( 0,0,0 );
|
volTool.GetBaryCenter( bc[0], bc[1], bc[2] );
|
||||||
gc = accumulate( NXyzIterator((*elem)->nodesIterator()), xyzEnd, gc ) / nodes.size();
|
SMDS_MeshNode* gcNode = helper.AddNode( bc[0], bc[1], bc[2] );
|
||||||
SMDS_MeshNode* gcNode = helper.AddNode( gc.X(), gc.Y(), gc.Z() );
|
|
||||||
nodes.push_back( gcNode );
|
nodes.push_back( gcNode );
|
||||||
newNodes.Append( gcNode );
|
newNodes.Append( gcNode );
|
||||||
}
|
}
|
||||||
|
if ( !splitMethod._faceBaryNode.empty() )
|
||||||
|
{
|
||||||
|
// make or find baricentric nodes of faces
|
||||||
|
map<int, const SMDS_MeshNode*>::iterator iF_n = splitMethod._faceBaryNode.begin();
|
||||||
|
for ( ; iF_n != splitMethod._faceBaryNode.end(); ++iF_n )
|
||||||
|
{
|
||||||
|
map< TVolumeFaceKey, const SMDS_MeshNode* >::iterator f_n =
|
||||||
|
volFace2BaryNode.insert
|
||||||
|
( make_pair( TVolumeFaceKey( volTool,iF_n->first ), (const SMDS_MeshNode*)0) ).first;
|
||||||
|
if ( !f_n->second )
|
||||||
|
{
|
||||||
|
volTool.GetFaceBaryCenter( iF_n->first, bc[0], bc[1], bc[2] );
|
||||||
|
newNodes.Append( f_n->second = helper.AddNode( bc[0], bc[1], bc[2] ));
|
||||||
|
}
|
||||||
|
nodes.push_back( iF_n->second = f_n->second );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// make tetras
|
// make tetras
|
||||||
helper.SetElementsOnShape( true );
|
helper.SetElementsOnShape( true );
|
||||||
@ -1547,6 +1615,25 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems,
|
|||||||
vector<const SMDS_MeshNode*> fNodes( volTool.GetFaceNodes( iF ),
|
vector<const SMDS_MeshNode*> fNodes( volTool.GetFaceNodes( iF ),
|
||||||
volTool.GetFaceNodes( iF ) + nbNodes*iQ );
|
volTool.GetFaceNodes( iF ) + nbNodes*iQ );
|
||||||
while ( const SMDS_MeshElement* face = GetMeshDS()->FindFace( fNodes ))
|
while ( const SMDS_MeshElement* face = GetMeshDS()->FindFace( fNodes ))
|
||||||
|
{
|
||||||
|
// make triangles
|
||||||
|
helper.SetElementsOnShape( false );
|
||||||
|
vector< const SMDS_MeshElement* > triangles;
|
||||||
|
|
||||||
|
map<int, const SMDS_MeshNode*>::iterator iF_n = splitMethod._faceBaryNode.find(iF);
|
||||||
|
if ( iF_n != splitMethod._faceBaryNode.end() )
|
||||||
|
{
|
||||||
|
for ( int iN = 0; iN < nbNodes*iQ; iN += iQ )
|
||||||
|
{
|
||||||
|
const SMDS_MeshNode* n1 = fNodes[iN];
|
||||||
|
const SMDS_MeshNode *n2 = fNodes[(iN+iQ)%nbNodes*iQ];
|
||||||
|
const SMDS_MeshNode *n3 = iF_n->second;
|
||||||
|
if ( !volTool.IsFaceExternal( iF ))
|
||||||
|
swap( n2, n3 );
|
||||||
|
triangles.push_back( helper.AddFace( n1,n2,n3 ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// among possible triangles create ones discribed by split method
|
// among possible triangles create ones discribed by split method
|
||||||
const int* nInd = volTool.GetFaceNodesIndices( iF );
|
const int* nInd = volTool.GetFaceNodesIndices( iF );
|
||||||
@ -1572,15 +1659,6 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// find submesh to add new faces in
|
|
||||||
if ( !fSubMesh || !fSubMesh->Contains( face ))
|
|
||||||
{
|
|
||||||
int shapeID = FindShape( face );
|
|
||||||
fSubMesh = GetMeshDS()->MeshElements( shapeID );
|
|
||||||
}
|
|
||||||
// make triangles
|
|
||||||
helper.SetElementsOnShape( false );
|
|
||||||
vector< const SMDS_MeshElement* > triangles;
|
|
||||||
list< TTriangleFacet >::iterator facet = facets.begin();
|
list< TTriangleFacet >::iterator facet = facets.begin();
|
||||||
for ( ; facet != facets.end(); ++facet )
|
for ( ; facet != facets.end(); ++facet )
|
||||||
{
|
{
|
||||||
@ -1589,7 +1667,18 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems,
|
|||||||
triangles.push_back( helper.AddFace( volNodes[ facet->_n1 ],
|
triangles.push_back( helper.AddFace( volNodes[ facet->_n1 ],
|
||||||
volNodes[ facet->_n2 ],
|
volNodes[ facet->_n2 ],
|
||||||
volNodes[ facet->_n3 ]));
|
volNodes[ facet->_n3 ]));
|
||||||
if ( triangles.back() && fSubMesh )
|
}
|
||||||
|
}
|
||||||
|
// find submesh to add new triangles in
|
||||||
|
if ( !fSubMesh || !fSubMesh->Contains( face ))
|
||||||
|
{
|
||||||
|
int shapeID = FindShape( face );
|
||||||
|
fSubMesh = GetMeshDS()->MeshElements( shapeID );
|
||||||
|
}
|
||||||
|
for ( int i = 0; i < triangles.size(); ++i )
|
||||||
|
{
|
||||||
|
if ( !triangles.back() ) continue;
|
||||||
|
if ( fSubMesh )
|
||||||
fSubMesh->AddElement( triangles.back());
|
fSubMesh->AddElement( triangles.back());
|
||||||
newElems.Append( triangles.back() );
|
newElems.Append( triangles.back() );
|
||||||
}
|
}
|
||||||
@ -8597,7 +8686,7 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm,
|
|||||||
int nbElem = 0;
|
int nbElem = 0;
|
||||||
if( !theSm ) return nbElem;
|
if( !theSm ) return nbElem;
|
||||||
|
|
||||||
const bool notFromGroups = false;
|
vector<int> nbNodeInFaces;
|
||||||
SMDS_ElemIteratorPtr ElemItr = theSm->GetElements();
|
SMDS_ElemIteratorPtr ElemItr = theSm->GetElements();
|
||||||
while(ElemItr->more())
|
while(ElemItr->more())
|
||||||
{
|
{
|
||||||
@ -8607,15 +8696,13 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm,
|
|||||||
|
|
||||||
int id = elem->GetID();
|
int id = elem->GetID();
|
||||||
int nbNodes = elem->NbNodes();
|
int nbNodes = elem->NbNodes();
|
||||||
vector<const SMDS_MeshNode *> aNds (nbNodes);
|
|
||||||
|
|
||||||
for(int i = 0; i < nbNodes; i++)
|
|
||||||
{
|
|
||||||
aNds[i] = elem->GetNode(i);
|
|
||||||
}
|
|
||||||
SMDSAbs_ElementType aType = elem->GetType();
|
SMDSAbs_ElementType aType = elem->GetType();
|
||||||
|
|
||||||
GetMeshDS()->RemoveFreeElement(elem, theSm, notFromGroups);
|
vector<const SMDS_MeshNode *> nodes (elem->begin_nodes(), elem->end_nodes());
|
||||||
|
if ( elem->GetEntityType() == SMDSEntity_Polyhedra )
|
||||||
|
nbNodeInFaces = static_cast<const SMDS_PolyhedralVolumeOfNodes* >( elem )->GetQuanities();
|
||||||
|
|
||||||
|
GetMeshDS()->RemoveFreeElement(elem, theSm, /*fromGroups=*/false);
|
||||||
|
|
||||||
const SMDS_MeshElement* NewElem = 0;
|
const SMDS_MeshElement* NewElem = 0;
|
||||||
|
|
||||||
@ -8623,7 +8710,7 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm,
|
|||||||
{
|
{
|
||||||
case SMDSAbs_Edge :
|
case SMDSAbs_Edge :
|
||||||
{
|
{
|
||||||
NewElem = theHelper.AddEdge(aNds[0], aNds[1], id, theForce3d);
|
NewElem = theHelper.AddEdge(nodes[0], nodes[1], id, theForce3d);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SMDSAbs_Face :
|
case SMDSAbs_Face :
|
||||||
@ -8631,12 +8718,13 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm,
|
|||||||
switch(nbNodes)
|
switch(nbNodes)
|
||||||
{
|
{
|
||||||
case 3:
|
case 3:
|
||||||
NewElem = theHelper.AddFace(aNds[0], aNds[1], aNds[2], id, theForce3d);
|
NewElem = theHelper.AddFace(nodes[0], nodes[1], nodes[2], id, theForce3d);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
NewElem = theHelper.AddFace(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d);
|
NewElem = theHelper.AddFace(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
NewElem = theHelper.AddPolygonalFace(nodes, id, theForce3d);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -8646,20 +8734,20 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm,
|
|||||||
switch(nbNodes)
|
switch(nbNodes)
|
||||||
{
|
{
|
||||||
case 4:
|
case 4:
|
||||||
NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d);
|
NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d);
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], aNds[4], id, theForce3d);
|
NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], id, theForce3d);
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], aNds[4], aNds[5], id, theForce3d);
|
NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], id, theForce3d);
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3],
|
NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3],
|
||||||
aNds[4], aNds[5], aNds[6], aNds[7], id, theForce3d);
|
nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
NewElem = theHelper.AddPolyhedralVolume(nodes, nbNodeInFaces, id, theForce3d);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -8683,7 +8771,6 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
|
|||||||
|
|
||||||
SMESH_MesherHelper aHelper(*myMesh);
|
SMESH_MesherHelper aHelper(*myMesh);
|
||||||
aHelper.SetIsQuadratic( true );
|
aHelper.SetIsQuadratic( true );
|
||||||
const bool notFromGroups = false;
|
|
||||||
|
|
||||||
int nbCheckedElems = 0;
|
int nbCheckedElems = 0;
|
||||||
if ( myMesh->HasShapeToMesh() )
|
if ( myMesh->HasShapeToMesh() )
|
||||||
@ -8714,7 +8801,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
|
|||||||
const SMDS_MeshNode* n1 = edge->GetNode(0);
|
const SMDS_MeshNode* n1 = edge->GetNode(0);
|
||||||
const SMDS_MeshNode* n2 = edge->GetNode(1);
|
const SMDS_MeshNode* n2 = edge->GetNode(1);
|
||||||
|
|
||||||
meshDS->RemoveFreeElement(edge, smDS, notFromGroups);
|
meshDS->RemoveFreeElement(edge, smDS, /*fromGroups=*/false);
|
||||||
|
|
||||||
const SMDS_MeshEdge* NewEdge = aHelper.AddEdge(n1, n2, id, theForce3d);
|
const SMDS_MeshEdge* NewEdge = aHelper.AddEdge(n1, n2, id, theForce3d);
|
||||||
ReplaceElemInGroups( edge, NewEdge, GetMeshDS());
|
ReplaceElemInGroups( edge, NewEdge, GetMeshDS());
|
||||||
@ -8728,29 +8815,25 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
|
|||||||
|
|
||||||
int id = face->GetID();
|
int id = face->GetID();
|
||||||
int nbNodes = face->NbNodes();
|
int nbNodes = face->NbNodes();
|
||||||
vector<const SMDS_MeshNode *> aNds (nbNodes);
|
vector<const SMDS_MeshNode *> nodes ( face->begin_nodes(), face->end_nodes());
|
||||||
|
|
||||||
for(int i = 0; i < nbNodes; i++)
|
meshDS->RemoveFreeElement(face, smDS, /*fromGroups=*/false);
|
||||||
{
|
|
||||||
aNds[i] = face->GetNode(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
meshDS->RemoveFreeElement(face, smDS, notFromGroups);
|
|
||||||
|
|
||||||
SMDS_MeshFace * NewFace = 0;
|
SMDS_MeshFace * NewFace = 0;
|
||||||
switch(nbNodes)
|
switch(nbNodes)
|
||||||
{
|
{
|
||||||
case 3:
|
case 3:
|
||||||
NewFace = aHelper.AddFace(aNds[0], aNds[1], aNds[2], id, theForce3d);
|
NewFace = aHelper.AddFace(nodes[0], nodes[1], nodes[2], id, theForce3d);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
NewFace = aHelper.AddFace(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d);
|
NewFace = aHelper.AddFace(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
NewFace = aHelper.AddPolygonalFace(nodes, id, theForce3d);
|
||||||
}
|
}
|
||||||
ReplaceElemInGroups( face, NewFace, GetMeshDS());
|
ReplaceElemInGroups( face, NewFace, GetMeshDS());
|
||||||
}
|
}
|
||||||
|
vector<int> nbNodeInFaces;
|
||||||
SMDS_VolumeIteratorPtr aVolumeItr = meshDS->volumesIterator();
|
SMDS_VolumeIteratorPtr aVolumeItr = meshDS->volumesIterator();
|
||||||
while(aVolumeItr->more())
|
while(aVolumeItr->more())
|
||||||
{
|
{
|
||||||
@ -8759,40 +8842,38 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
|
|||||||
|
|
||||||
int id = volume->GetID();
|
int id = volume->GetID();
|
||||||
int nbNodes = volume->NbNodes();
|
int nbNodes = volume->NbNodes();
|
||||||
vector<const SMDS_MeshNode *> aNds (nbNodes);
|
vector<const SMDS_MeshNode *> nodes (volume->begin_nodes(), volume->end_nodes());
|
||||||
|
if ( volume->GetEntityType() == SMDSEntity_Polyhedra )
|
||||||
|
nbNodeInFaces = static_cast<const SMDS_PolyhedralVolumeOfNodes* >(volume)->GetQuanities();
|
||||||
|
|
||||||
for(int i = 0; i < nbNodes; i++)
|
meshDS->RemoveFreeElement(volume, smDS, /*fromGroups=*/false);
|
||||||
{
|
|
||||||
aNds[i] = volume->GetNode(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
meshDS->RemoveFreeElement(volume, smDS, notFromGroups);
|
|
||||||
|
|
||||||
SMDS_MeshVolume * NewVolume = 0;
|
SMDS_MeshVolume * NewVolume = 0;
|
||||||
switch(nbNodes)
|
switch(nbNodes)
|
||||||
{
|
{
|
||||||
case 4:
|
case 4:
|
||||||
NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2],
|
NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2],
|
||||||
aNds[3], id, theForce3d );
|
nodes[3], id, theForce3d );
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2],
|
NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2],
|
||||||
aNds[3], aNds[4], id, theForce3d);
|
nodes[3], nodes[4], id, theForce3d);
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2],
|
NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2],
|
||||||
aNds[3], aNds[4], aNds[5], id, theForce3d);
|
nodes[3], nodes[4], nodes[5], id, theForce3d);
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3],
|
NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3],
|
||||||
aNds[4], aNds[5], aNds[6], aNds[7], id, theForce3d);
|
nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
NewVolume = aHelper.AddPolyhedralVolume(nodes, nbNodeInFaces, id, theForce3d);
|
||||||
}
|
}
|
||||||
ReplaceElemInGroups(volume, NewVolume, meshDS);
|
ReplaceElemInGroups(volume, NewVolume, meshDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !theForce3d && !getenv("NO_FixQuadraticElements"))
|
if ( !theForce3d && !getenv("NO_FixQuadraticElements"))
|
||||||
{ // setenv NO_FixQuadraticElements to know if FixQuadraticElements() is guilty of bad conversion
|
{ // setenv NO_FixQuadraticElements to know if FixQuadraticElements() is guilty of bad conversion
|
||||||
aHelper.SetSubShape(0); // apply FixQuadraticElements() to the whole mesh
|
aHelper.SetSubShape(0); // apply FixQuadraticElements() to the whole mesh
|
||||||
@ -8823,8 +8904,8 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh * theSm,
|
|||||||
{
|
{
|
||||||
int id = elem->GetID();
|
int id = elem->GetID();
|
||||||
int nbNodes = elem->NbNodes();
|
int nbNodes = elem->NbNodes();
|
||||||
vector<const SMDS_MeshNode *> aNds, mediumNodes;
|
vector<const SMDS_MeshNode *> nodes, mediumNodes;
|
||||||
aNds.reserve( nbNodes );
|
nodes.reserve( nbNodes );
|
||||||
mediumNodes.reserve( nbNodes );
|
mediumNodes.reserve( nbNodes );
|
||||||
|
|
||||||
for(int i = 0; i < nbNodes; i++)
|
for(int i = 0; i < nbNodes; i++)
|
||||||
@ -8834,15 +8915,15 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh * theSm,
|
|||||||
if( elem->IsMediumNode( n ) )
|
if( elem->IsMediumNode( n ) )
|
||||||
mediumNodes.push_back( n );
|
mediumNodes.push_back( n );
|
||||||
else
|
else
|
||||||
aNds.push_back( n );
|
nodes.push_back( n );
|
||||||
}
|
}
|
||||||
if( aNds.empty() ) continue;
|
if( nodes.empty() ) continue;
|
||||||
SMDSAbs_ElementType aType = elem->GetType();
|
SMDSAbs_ElementType aType = elem->GetType();
|
||||||
|
|
||||||
//remove old quadratic element
|
//remove old quadratic element
|
||||||
meshDS->RemoveFreeElement( elem, theSm, notFromGroups );
|
meshDS->RemoveFreeElement( elem, theSm, notFromGroups );
|
||||||
|
|
||||||
SMDS_MeshElement * NewElem = AddElement( aNds, aType, false, id );
|
SMDS_MeshElement * NewElem = AddElement( nodes, aType, false, id );
|
||||||
ReplaceElemInGroups(elem, NewElem, meshDS);
|
ReplaceElemInGroups(elem, NewElem, meshDS);
|
||||||
if( theSm && NewElem )
|
if( theSm && NewElem )
|
||||||
theSm->AddElement( NewElem );
|
theSm->AddElement( NewElem );
|
||||||
|
@ -245,7 +245,7 @@ public:
|
|||||||
SMESH::Controls::NumericalFunctorPtr theCriterion);
|
SMESH::Controls::NumericalFunctorPtr theCriterion);
|
||||||
|
|
||||||
|
|
||||||
enum SplitVolumToTetraFlags { HEXA_TO_5 = 1, HEXA_TO_6 = 2 };//!<arg of SplitVolumesIntoTetra()
|
enum SplitVolumToTetraFlags { HEXA_TO_5 = 1, HEXA_TO_6 = 2, HEXA_TO_24 = 3 };//!<arg of SplitVolumesIntoTetra()
|
||||||
/*!
|
/*!
|
||||||
* \brief Split volumic elements into tetrahedra.
|
* \brief Split volumic elements into tetrahedra.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user