0021859: SMESH : Add conversion from QUAD8 to QUAD9 and from HEXA20 to HEXA27

-  void ConvertToQuadratic(const bool theForce3d);
+  void ConvertToQuadratic(const bool theForce3d, const bool theToBiQuad);
This commit is contained in:
eap 2013-03-06 08:12:22 +00:00
parent f0cd60b411
commit b3b654c67b
2 changed files with 78 additions and 27 deletions

View File

@ -9587,14 +9587,26 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm,
{ {
nbElem++; nbElem++;
const SMDS_MeshElement* elem = ElemItr->next(); const SMDS_MeshElement* elem = ElemItr->next();
if( !elem || elem->IsQuadratic() ) continue; if( !elem ) continue;
const SMDSAbs_EntityType aGeomType = elem->GetEntityType();
if ( elem->IsQuadratic() )
{
bool alreadyOK;
switch ( aGeomType ) {
case SMDSEntity_Quad_Quadrangle:
case SMDSEntity_Quad_Hexa: alreadyOK = !theHelper.GetIsBiQuadratic(); break;
case SMDSEntity_BiQuad_Quadrangle:
case SMDSEntity_TriQuad_Hexa: alreadyOK = theHelper.GetIsBiQuadratic(); break;
default: alreadyOK = true;
}
if ( alreadyOK ) continue;
}
// get elem data needed to re-create it // get elem data needed to re-create it
// //
const int id = elem->GetID(); const int id = elem->GetID();
const int nbNodes = elem->NbNodes(); const int nbNodes = elem->NbCornerNodes();
const SMDSAbs_ElementType aType = elem->GetType(); const SMDSAbs_ElementType aType = elem->GetType();
const SMDSAbs_EntityType aGeomType = elem->GetEntityType();
nodes.assign(elem->begin_nodes(), elem->end_nodes()); nodes.assign(elem->begin_nodes(), elem->end_nodes());
if ( aGeomType == SMDSEntity_Polyhedra ) if ( aGeomType == SMDSEntity_Polyhedra )
nbNodeInFaces = static_cast<const SMDS_VtkVolume* >( elem )->GetQuantities(); nbNodeInFaces = static_cast<const SMDS_VtkVolume* >( elem )->GetQuantities();
@ -9643,6 +9655,8 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm,
NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], id, theForce3d); NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], id, theForce3d);
break; break;
case SMDSEntity_Hexa: case SMDSEntity_Hexa:
case SMDSEntity_Quad_Hexa:
case SMDSEntity_TriQuad_Hexa:
NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3],
nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d); nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d);
break; break;
@ -9661,18 +9675,20 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm,
} }
return nbElem; return nbElem;
} }
//======================================================================= //=======================================================================
//function : ConvertToQuadratic //function : ConvertToQuadratic
//purpose : //purpose :
//======================================================================= //=======================================================================
void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theToBiQuad)
{ {
SMESHDS_Mesh* meshDS = GetMeshDS(); SMESHDS_Mesh* meshDS = GetMeshDS();
SMESH_MesherHelper aHelper(*myMesh); SMESH_MesherHelper aHelper(*myMesh);
aHelper.SetIsQuadratic( true ); aHelper.SetIsQuadratic( true );
aHelper.SetIsBiQuadratic( theToBiQuad );
aHelper.SetElementsOnShape(true);
int nbCheckedElems = 0; int nbCheckedElems = 0;
if ( myMesh->HasShapeToMesh() ) if ( myMesh->HasShapeToMesh() )
@ -9714,10 +9730,14 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
while(aFaceItr->more()) while(aFaceItr->more())
{ {
const SMDS_MeshFace* face = aFaceItr->next(); const SMDS_MeshFace* face = aFaceItr->next();
if(!face || face->IsQuadratic() ) continue; if ( !face ) continue;
const SMDSAbs_EntityType type = face->GetEntityType();
if (( theToBiQuad && type == SMDSEntity_BiQuad_Quadrangle ) ||
( !theToBiQuad && type == SMDSEntity_Quad_Quadrangle ))
continue;
const int id = face->GetID(); const int id = face->GetID();
const SMDSAbs_EntityType type = face->GetEntityType();
vector<const SMDS_MeshNode *> nodes ( face->begin_nodes(), face->end_nodes()); vector<const SMDS_MeshNode *> nodes ( face->begin_nodes(), face->end_nodes());
meshDS->RemoveFreeElement(face, smDS, /*fromGroups=*/false); meshDS->RemoveFreeElement(face, smDS, /*fromGroups=*/false);
@ -9743,8 +9763,12 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
const SMDS_MeshVolume* volume = aVolumeItr->next(); const SMDS_MeshVolume* volume = aVolumeItr->next();
if(!volume || volume->IsQuadratic() ) continue; if(!volume || volume->IsQuadratic() ) continue;
const int id = volume->GetID();
const SMDSAbs_EntityType type = volume->GetEntityType(); const SMDSAbs_EntityType type = volume->GetEntityType();
if (( theToBiQuad && type == SMDSEntity_TriQuad_Hexa ) ||
( !theToBiQuad && type == SMDSEntity_Quad_Hexa ))
continue;
const int id = volume->GetID();
vector<const SMDS_MeshNode *> nodes (volume->begin_nodes(), volume->end_nodes()); vector<const SMDS_MeshNode *> nodes (volume->begin_nodes(), volume->end_nodes());
if ( type == SMDSEntity_Polyhedra ) if ( type == SMDSEntity_Polyhedra )
nbNodeInFaces = static_cast<const SMDS_VtkVolume* >(volume)->GetQuantities(); nbNodeInFaces = static_cast<const SMDS_VtkVolume* >(volume)->GetQuantities();
@ -9760,6 +9784,8 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d ); NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d );
break; break;
case SMDSEntity_Hexa: case SMDSEntity_Hexa:
case SMDSEntity_Quad_Hexa:
case SMDSEntity_TriQuad_Hexa:
NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3],
nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d); nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d);
break; break;
@ -9795,7 +9821,8 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
//================================================================================ //================================================================================
void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d,
TIDSortedElemSet& theElements) TIDSortedElemSet& theElements,
const bool theToBiQuad)
{ {
if ( theElements.empty() ) return; if ( theElements.empty() ) return;
@ -9822,8 +9849,19 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d,
const SMDS_MeshElement* e = invIt->next(); const SMDS_MeshElement* e = invIt->next();
if ( e->IsQuadratic() ) if ( e->IsQuadratic() )
{ {
quadAdjacentElems[ e->GetType() ].insert( e ); bool alreadyOK;
continue; switch ( e->GetEntityType() ) {
case SMDSEntity_Quad_Quadrangle:
case SMDSEntity_Quad_Hexa: alreadyOK = !theToBiQuad; break;
case SMDSEntity_BiQuad_Quadrangle:
case SMDSEntity_TriQuad_Hexa: alreadyOK = theToBiQuad; break;
default: alreadyOK = true;
}
if ( alreadyOK )
{
quadAdjacentElems[ e->GetType() ].insert( e );
continue;
}
} }
if ( e->GetType() >= elemType ) if ( e->GetType() >= elemType )
{ {
@ -9845,6 +9883,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d,
SMESH_MesherHelper helper(*myMesh); SMESH_MesherHelper helper(*myMesh);
helper.SetIsQuadratic( true ); helper.SetIsQuadratic( true );
helper.SetIsBiQuadratic( theToBiQuad );
// add links of quadratic adjacent elements to the helper // add links of quadratic adjacent elements to the helper
@ -9867,18 +9906,32 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d,
helper.AddTLinks( static_cast< const SMDS_MeshVolume*> (*eIt) ); helper.AddTLinks( static_cast< const SMDS_MeshVolume*> (*eIt) );
} }
// make quadratic elements instead of linear ones // make quadratic (or bi-tri-quadratic) elements instead of linear ones
SMESHDS_Mesh* meshDS = GetMeshDS(); SMESHDS_Mesh* meshDS = GetMeshDS();
SMESHDS_SubMesh* smDS = 0; SMESHDS_SubMesh* smDS = 0;
for ( eIt = theElements.begin(); eIt != theElements.end(); ++eIt ) for ( eIt = theElements.begin(); eIt != theElements.end(); ++eIt )
{ {
const SMDS_MeshElement* elem = *eIt; const SMDS_MeshElement* elem = *eIt;
if( elem->IsQuadratic() || elem->NbNodes() < 2 || elem->IsPoly() ) if( elem->NbNodes() < 2 || elem->IsPoly() )
continue; continue;
const int id = elem->GetID(); if ( elem->IsQuadratic() )
{
bool alreadyOK;
switch ( elem->GetEntityType() ) {
case SMDSEntity_Quad_Quadrangle:
case SMDSEntity_Quad_Hexa: alreadyOK = !theToBiQuad; break;
case SMDSEntity_BiQuad_Quadrangle:
case SMDSEntity_TriQuad_Hexa: alreadyOK = theToBiQuad; break;
default: alreadyOK = true;
}
if ( alreadyOK ) continue;
}
const SMDSAbs_ElementType type = elem->GetType(); const SMDSAbs_ElementType type = elem->GetType();
const int id = elem->GetID();
const int nbNodes = elem->NbCornerNodes();
vector<const SMDS_MeshNode *> nodes ( elem->begin_nodes(), elem->end_nodes()); vector<const SMDS_MeshNode *> nodes ( elem->begin_nodes(), elem->end_nodes());
if ( !smDS || !smDS->Contains( elem )) if ( !smDS || !smDS->Contains( elem ))
@ -9886,7 +9939,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d,
meshDS->RemoveFreeElement(elem, smDS, /*fromGroups=*/false); meshDS->RemoveFreeElement(elem, smDS, /*fromGroups=*/false);
SMDS_MeshElement * newElem = 0; SMDS_MeshElement * newElem = 0;
switch( nodes.size() ) switch( nbNodes )
{ {
case 4: // cases for most frequently used element types go first (for optimization) case 4: // cases for most frequently used element types go first (for optimization)
if ( type == SMDSAbs_Volume ) if ( type == SMDSAbs_Volume )

View File

@ -117,7 +117,6 @@ public:
const SMESH_SequenceOfElemPtr& GetLastCreatedNodes() const { return myLastCreatedNodes; } const SMESH_SequenceOfElemPtr& GetLastCreatedNodes() const { return myLastCreatedNodes; }
const SMESH_SequenceOfElemPtr& GetLastCreatedElems() const { return myLastCreatedElems; } const SMESH_SequenceOfElemPtr& GetLastCreatedElems() const { return myLastCreatedElems; }
void CrearLastCreated(); void CrearLastCreated();
SMESH_ComputeErrorPtr & GetError() { return myError; } SMESH_ComputeErrorPtr & GetError() { return myError; }
/*! /*!
@ -492,15 +491,15 @@ public:
// insert theNodesToInsert into all volumes, containing link // insert theNodesToInsert into all volumes, containing link
// theBetweenNode1 - theBetweenNode2, between theBetweenNode1 and theBetweenNode2. // theBetweenNode1 - theBetweenNode2, between theBetweenNode1 and theBetweenNode2.
void ConvertToQuadratic(const bool theForce3d); void ConvertToQuadratic(const bool theForce3d, const bool theToBiQuad);
void ConvertToQuadratic(const bool theForce3d, TIDSortedElemSet& theElements); void ConvertToQuadratic(const bool theForce3d,
// Converts all mesh to quadratic one, deletes old elements, replacing TIDSortedElemSet& theElements, const bool theToBiQuad);
// them with quadratic ones with the same id. // Converts all mesh to quadratic or bi-quadratic one, deletes old elements,
// replacing them with quadratic or bi-quadratic ones with the same id.
// If theForce3d = 1; this results in the medium node lying at the // If theForce3d = 1; this results in the medium node lying at the
// middle of the line segments connecting start and end node of a mesh // middle of the line segments connecting start and end node of a mesh element.
// element
// If theForce3d = 0; this results in the medium node lying at the // If theForce3d = 0; this results in the medium node lying at the
// geometrical edge from which the mesh element is built // geometrical edge from which the mesh element is built.
bool ConvertFromQuadratic(); bool ConvertFromQuadratic();
void ConvertFromQuadratic(TIDSortedElemSet& theElements); void ConvertFromQuadratic(TIDSortedElemSet& theElements);
@ -625,7 +624,6 @@ public:
bool toAddExistingBondary = false, bool toAddExistingBondary = false,
bool aroundElements = false); bool aroundElements = false);
private: private:
/*! /*!