Make QuadToTri() put new nodes of quadratic triangles on a surface

This commit is contained in:
eap 2006-05-06 06:23:48 +00:00
parent a2797078a4
commit 3c8cb0e08e

View File

@ -41,6 +41,7 @@
#include "SMESH_subMesh.hxx" #include "SMESH_subMesh.hxx"
#include "SMESH_ControlsDef.hxx" #include "SMESH_ControlsDef.hxx"
#include "SMESH_MesherHelper.hxx"
#include "utilities.h" #include "utilities.h"
@ -65,6 +66,7 @@
#include <GeomAdaptor_Surface.hxx> #include <GeomAdaptor_Surface.hxx>
#include <ElCLib.hxx> #include <ElCLib.hxx>
#include <TColStd_ListOfInteger.hxx> #include <TColStd_ListOfInteger.hxx>
#include <TopoDS_Face.hxx>
#include <map> #include <map>
@ -824,16 +826,19 @@ bool SMESH_MeshEditor::QuadToTri (map<int,const SMDS_MeshElement*> & theEl
SMESHDS_Mesh * aMesh = GetMeshDS(); SMESHDS_Mesh * aMesh = GetMeshDS();
Handle(Geom_Surface) surface;
SMESH_MesherHelper helper( *GetMesh() );
map<int, const SMDS_MeshElement * >::iterator itElem; map<int, const SMDS_MeshElement * >::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
const SMDS_MeshElement* elem = (*itElem).second; const SMDS_MeshElement* elem = (*itElem).second;
if ( !elem || elem->GetType() != SMDSAbs_Face ) if ( !elem || elem->GetType() != SMDSAbs_Face )
continue; continue;
if ( elem->NbNodes() != ( elem->IsQuadratic() ? 8 : 4 ))
if(elem->NbNodes()==4) { continue;
// retrieve element nodes // retrieve element nodes
const SMDS_MeshNode* aNodes [4]; const SMDS_MeshNode* aNodes [8];
SMDS_ElemIteratorPtr itN = elem->nodesIterator(); SMDS_ElemIteratorPtr itN = elem->nodesIterator();
int i = 0; int i = 0;
while ( itN->more() ) while ( itN->more() )
@ -850,96 +855,104 @@ bool SMESH_MeshEditor::QuadToTri (map<int,const SMDS_MeshElement*> & theEl
aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit ); aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit );
int aShapeId = FindShape( elem ); int aShapeId = FindShape( elem );
//MESSAGE( "aBadRate1 = " << aBadRate1 << "; aBadRate2 = " << aBadRate2 const SMDS_MeshElement* newElem = 0;
// << " ShapeID = " << aShapeId << endl << elem );
if( !elem->IsQuadratic() ) {
// split liner quadrangle
if ( aBadRate1 <= aBadRate2 ) { if ( aBadRate1 <= aBadRate2 ) {
// tr1 + tr2 is better // tr1 + tr2 is better
aMesh->ChangeElementNodes( elem, aNodes, 3 ); aMesh->ChangeElementNodes( elem, aNodes, 3 );
//MESSAGE( endl << elem ); newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
elem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
} }
else { else {
// tr3 + tr4 is better // tr3 + tr4 is better
aMesh->ChangeElementNodes( elem, &aNodes[1], 3 ); aMesh->ChangeElementNodes( elem, &aNodes[1], 3 );
//MESSAGE( endl << elem ); newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
elem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
} }
//MESSAGE( endl << elem );
myLastCreatedElems.Append(elem);
// put a new triangle on the same shape
if ( aShapeId )
aMesh->SetMeshElementOnShape( elem, aShapeId );
} }
else {
if( elem->NbNodes()==8 && elem->IsQuadratic() ) { // split qudratic quadrangle
// get surface elem is on
if ( aShapeId != helper.GetSubShapeID() ) {
surface.Nullify();
TopoDS_Shape shape = aMesh->IndexToShape( aShapeId );
if ( !shape.IsNull() && shape.ShapeType() == TopAbs_FACE ) {
TopoDS_Face face = TopoDS::Face( shape );
surface = BRep_Tool::Surface( face );
if ( !surface.IsNull() )
helper.SetSubShape( shape );
}
}
// get elem nodes
const SMDS_MeshNode* aNodes [8]; const SMDS_MeshNode* aNodes [8];
const SMDS_MeshNode* inFaceNode = 0;
SMDS_ElemIteratorPtr itN = elem->nodesIterator(); SMDS_ElemIteratorPtr itN = elem->nodesIterator();
int i = 0; int i = 0;
while ( itN->more() ) { while ( itN->more() ) {
aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() ); aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
if ( !inFaceNode && helper.GetNodeUVneedInFaceNode() &&
aNodes[ i-1 ]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
{
inFaceNode = aNodes[ i-1 ];
}
} }
// compare two sets of possible triangles
// use for comparing simple triangles (not quadratic)
double aBadRate1, aBadRate2; // to what extent a set is bad
SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] );
SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] );
aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit );
SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] );
SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] );
aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit );
int aShapeId = FindShape( elem );
// find middle point for (0,1,2,3) // find middle point for (0,1,2,3)
// and create node in this point; // and create a node in this point;
double x=0., y=0., z=0.; gp_XYZ p( 0,0,0 );
for(i=0; i<4; i++) { if ( surface.IsNull() ) {
x += aNodes[i]->X(); for(i=0; i<4; i++)
y += aNodes[i]->Y(); p += gp_XYZ(aNodes[i]->X(), aNodes[i]->Y(), aNodes[i]->Z() );
z += aNodes[i]->Z(); p /= 4;
} }
const SMDS_MeshNode* newN = aMesh->AddNode(x/4, y/4, z/4); else {
TopoDS_Face face = TopoDS::Face( helper.GetSubShape() );
gp_XY uv( 0,0 );
for(i=0; i<4; i++)
uv += helper.GetNodeUV( face, aNodes[i], inFaceNode );
uv /= 4.;
p = surface->Value( uv.X(), uv.Y() ).XYZ();
}
const SMDS_MeshNode* newN = aMesh->AddNode( p.X(), p.Y(), p.Z() );
myLastCreatedNodes.Append(newN); myLastCreatedNodes.Append(newN);
if ( aBadRate1 <= aBadRate2 ) { // create a new element
// tr1 + tr2 is better
const SMDS_MeshNode* N[6]; const SMDS_MeshNode* N[6];
if ( aBadRate1 <= aBadRate2 ) {
N[0] = aNodes[0]; N[0] = aNodes[0];
N[1] = aNodes[1]; N[1] = aNodes[1];
N[2] = aNodes[2]; N[2] = aNodes[2];
N[3] = aNodes[4]; N[3] = aNodes[4];
N[4] = aNodes[5]; N[4] = aNodes[5];
N[5] = newN; N[5] = newN;
aMesh->ChangeElementNodes( elem, N, 6 ); newElem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
elem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
aNodes[6], aNodes[7], newN ); aNodes[6], aNodes[7], newN );
} }
else { else {
// tr3 + tr4 is better
const SMDS_MeshNode* N[6];
N[0] = aNodes[1]; N[0] = aNodes[1];
N[1] = aNodes[2]; N[1] = aNodes[2];
N[2] = aNodes[3]; N[2] = aNodes[3];
N[3] = aNodes[5]; N[3] = aNodes[5];
N[4] = aNodes[6]; N[4] = aNodes[6];
N[5] = newN; N[5] = newN;
aMesh->ChangeElementNodes( elem, N, 6 ); newElem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
elem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
aNodes[7], aNodes[4], newN ); aNodes[7], aNodes[4], newN );
} }
myLastCreatedElems.Append(elem); aMesh->ChangeElementNodes( elem, N, 6 );
// put a new triangle on the same shape
if ( aShapeId ) {
aMesh->SetMeshElementOnShape( elem, aShapeId );
}
}
} // qudratic case
// care of a new element
myLastCreatedElems.Append(newElem);
AddToSameGroups( newElem, elem, aMesh );
// put a new triangle on the same shape
if ( aShapeId )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
} }
return true; return true;
} }
@ -1045,6 +1058,9 @@ bool SMESH_MeshEditor::QuadToTri (std::map<int,const SMDS_MeshElement*> & theEle
SMESHDS_Mesh * aMesh = GetMeshDS(); SMESHDS_Mesh * aMesh = GetMeshDS();
Handle(Geom_Surface) surface;
SMESH_MesherHelper helper( *GetMesh() );
map<int, const SMDS_MeshElement * >::iterator itElem; map<int, const SMDS_MeshElement * >::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
const SMDS_MeshElement* elem = (*itElem).second; const SMDS_MeshElement* elem = (*itElem).second;
@ -1078,52 +1094,80 @@ bool SMESH_MeshEditor::QuadToTri (std::map<int,const SMDS_MeshElement*> & theEle
AddToSameGroups( newElem, elem, aMesh ); AddToSameGroups( newElem, elem, aMesh );
} }
// Quadratic quadrangle
if( elem->NbNodes()==8 && elem->IsQuadratic() ) { if( elem->NbNodes()==8 && elem->IsQuadratic() ) {
// get surface elem is on
int aShapeId = FindShape( elem );
if ( aShapeId != helper.GetSubShapeID() ) {
surface.Nullify();
TopoDS_Shape shape = aMesh->IndexToShape( aShapeId );
if ( !shape.IsNull() && shape.ShapeType() == TopAbs_FACE ) {
TopoDS_Face face = TopoDS::Face( shape );
surface = BRep_Tool::Surface( face );
if ( !surface.IsNull() )
helper.SetSubShape( shape );
}
}
const SMDS_MeshNode* aNodes [8]; const SMDS_MeshNode* aNodes [8];
const SMDS_MeshNode* inFaceNode = 0;
SMDS_ElemIteratorPtr itN = elem->nodesIterator(); SMDS_ElemIteratorPtr itN = elem->nodesIterator();
int i = 0; int i = 0;
while ( itN->more() ) { while ( itN->more() ) {
aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() ); aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
if ( !inFaceNode && helper.GetNodeUVneedInFaceNode() &&
aNodes[ i-1 ]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
{
inFaceNode = aNodes[ i-1 ];
}
} }
// find middle point for (0,1,2,3) // find middle point for (0,1,2,3)
// and create node in this point; // and create a node in this point;
double x=0., y=0., z=0.; gp_XYZ p( 0,0,0 );
for(i=0; i<4; i++) { if ( surface.IsNull() ) {
x += aNodes[i]->X(); for(i=0; i<4; i++)
y += aNodes[i]->Y(); p += gp_XYZ(aNodes[i]->X(), aNodes[i]->Y(), aNodes[i]->Z() );
z += aNodes[i]->Z(); p /= 4;
} }
const SMDS_MeshNode* newN = aMesh->AddNode(x/4, y/4, z/4); else {
TopoDS_Face geomFace = TopoDS::Face( helper.GetSubShape() );
gp_XY uv( 0,0 );
for(i=0; i<4; i++)
uv += helper.GetNodeUV( geomFace, aNodes[i], inFaceNode );
uv /= 4.;
p = surface->Value( uv.X(), uv.Y() ).XYZ();
}
const SMDS_MeshNode* newN = aMesh->AddNode( p.X(), p.Y(), p.Z() );
myLastCreatedNodes.Append(newN); myLastCreatedNodes.Append(newN);
int aShapeId = FindShape( elem ); // create a new element
const SMDS_MeshElement* newElem = 0; const SMDS_MeshElement* newElem = 0;
if ( the13Diag ) {
const SMDS_MeshNode* N[6]; const SMDS_MeshNode* N[6];
if ( the13Diag ) {
N[0] = aNodes[0]; N[0] = aNodes[0];
N[1] = aNodes[1]; N[1] = aNodes[1];
N[2] = aNodes[2]; N[2] = aNodes[2];
N[3] = aNodes[4]; N[3] = aNodes[4];
N[4] = aNodes[5]; N[4] = aNodes[5];
N[5] = newN; N[5] = newN;
aMesh->ChangeElementNodes( elem, N, 6 ); newElem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
elem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
aNodes[6], aNodes[7], newN ); aNodes[6], aNodes[7], newN );
} }
else { else {
const SMDS_MeshNode* N[6];
N[0] = aNodes[1]; N[0] = aNodes[1];
N[1] = aNodes[2]; N[1] = aNodes[2];
N[2] = aNodes[3]; N[2] = aNodes[3];
N[3] = aNodes[5]; N[3] = aNodes[5];
N[4] = aNodes[6]; N[4] = aNodes[6];
N[5] = newN; N[5] = newN;
aMesh->ChangeElementNodes( elem, N, 6 ); newElem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
elem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
aNodes[7], aNodes[4], newN ); aNodes[7], aNodes[4], newN );
} }
myLastCreatedElems.Append(elem); myLastCreatedElems.Append(newElem);
aMesh->ChangeElementNodes( elem, N, 6 );
// put a new triangle on the same shape and add to the same groups // put a new triangle on the same shape and add to the same groups
if ( aShapeId ) if ( aShapeId )
aMesh->SetMeshElementOnShape( newElem, aShapeId ); aMesh->SetMeshElementOnShape( newElem, aShapeId );