#include "SMESH_subMesh.hxx"
#include "SMESH_ControlsDef.hxx"
#include "SMESH_MesherHelper.hxx"
+#include "SMESH_OctreeNode.hxx"
#include "utilities.h"
//=======================================================================
//function : IsMedium
-//purpose :
+//purpose :
//=======================================================================
bool SMESH_MeshEditor::IsMedium(const SMDS_MeshNode* node,
ShiftNodesQuadTria(N2);
}
// now we receive following N1 and N2 (using numeration as above image)
- // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
+ // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
// i.e. first nodes from both arrays determ new diagonal
return true;
}
SMDS_ElemIteratorPtr it = theTria1->nodesIterator();
while ( it->more() ) {
aNodes[ i ] = static_cast<const SMDS_MeshNode*>( it->next() );
-
+
if ( i > 2 ) // theTria2
// find same node of theTria1
for ( int j = 0; j < 3; j++ )
if ( i == 6 && it->more() )
return false; // theTria2 is not a triangle
}
-
+
// find indices of 1,2 and of A,B in theTria1
int iA = 0, iB = 0, i1 = 0, i2 = 0;
for ( i = 0; i < 6; i++ ) {
aNodes[ sameInd[ iB ]] = aNodes[ i1 ];
//MESSAGE( theTria1 << theTria2 );
-
+
GetMeshDS()->ChangeElementNodes( theTria1, aNodes, 3 );
GetMeshDS()->ChangeElementNodes( theTria2, &aNodes[ 3 ], 3 );
-
+
//MESSAGE( theTria1 << theTria2 );
return true;
-
+
} // end if(F1 && F2)
// check case of quadratic faces
// 5
// 1 +--+--+ 2 theTria1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9)
// | /| theTria2: (2 3 4 6 8 9) or (3 4 2 8 9 6) or (4 2 3 9 6 8)
- // | / |
+ // | / |
// 7 + + + 6
// | /9 |
// |/ |
- // 4 +--+--+ 3
+ // 4 +--+--+ 3
// 8
-
+
const SMDS_MeshNode* N1 [6];
const SMDS_MeshNode* N2 [6];
if(!GetNodesFromTwoTria(theTria1,theTria2,N1,N2))
return false;
// now we receive following N1 and N2 (using numeration as above image)
- // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
+ // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
// i.e. first nodes from both arrays determ new diagonal
const SMDS_MeshNode* N1new [6];
else if ( aNodes2[ i ] != theNode1 )
i2 = i; // node 2
}
-
+
// nodes 1 and 2 should not be the same
if ( aNodes1[ i1 ] == aNodes2[ i2 ] )
return false;
GetMeshDS()->ChangeElementNodes( tr2, aNodes2, 3 );
//MESSAGE( tr1 << tr2 );
-
+
return true;
}
// 5
// 1 +--+--+ 2 tr1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9)
// | /| tr2: (2 3 4 6 8 9) or (3 4 2 8 9 6) or (4 2 3 9 6 8)
- // | / |
+ // | / |
// 7 + + + 6
// | /9 |
// |/ |
- // 4 +--+--+ 3
+ // 4 +--+--+ 3
// 8
-
+
const SMDS_MeshNode* N1 [6];
const SMDS_MeshNode* N2 [6];
if(!GetNodesFromTwoTria(tr1,tr2,N1,N2))
return false;
// now we receive following N1 and N2 (using numeration as above image)
- // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
+ // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
// i.e. first nodes from both arrays determ new diagonal
const SMDS_MeshNode* aNodes[8];
for (int iface = 1; iface <= nbFaces; iface++) {
int inode, nbFaceNodes = aPolyedre->NbFaceNodes(iface);
quantities[iface - 1] = nbFaceNodes;
-
+
for (inode = nbFaceNodes; inode >= 1; inode--) {
const SMDS_MeshNode* curNode = aPolyedre->GetFaceNode(iface, inode);
poly_nodes.push_back(curNode);
}
}
-
+
return GetMeshDS()->ChangePolyhedronNodes( theElem, poly_nodes, quantities );
}
aNodes[ i-1 ]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
{
inFaceNode = aNodes[ i-1 ];
- }
+ }
}
// find middle point for (0,1,2,3)
// and create a node in this point;
SMESHDS_Mesh * aMesh)
{
const set<SMESHDS_GroupBase*>& groups = aMesh->GetGroups();
- if (!groups.empty())
+ if (!groups.empty())
{
set<SMESHDS_GroupBase*>::const_iterator GrIt = groups.begin();
- for (; GrIt != groups.end(); GrIt++)
+ for (; GrIt != groups.end(); GrIt++)
{
SMESHDS_Group* grp = dynamic_cast<SMESHDS_Group*>(*GrIt);
if (!grp || grp->IsEmpty()) continue;
aNodes[ i-1 ]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
{
inFaceNode = aNodes[ i-1 ];
- }
+ }
}
// find middle point for (0,1,2,3)
const SMDS_MeshNode* N2 [6];
GetNodesFromTwoTria(tr1,tr2,N1,N2);
// now we receive following N1 and N2 (using numeration as above image)
- // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
+ // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
// i.e. first nodes from both arrays determ new diagonal
const SMDS_MeshNode* aNodes[8];
aNodes[0] = N1[0];
const SMDS_MeshNode* N2 [6];
GetNodesFromTwoTria(tr1,tr3,N1,N2);
// now we receive following N1 and N2 (using numeration as above image)
- // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
+ // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
// i.e. first nodes from both arrays determ new diagonal
const SMDS_MeshNode* aNodes[8];
aNodes[0] = N1[0];
gp_XY uv2 = helper.GetNodeUV( face, Ns[i+2], Ns[i] );
gp_XY uv = ( uv1 + uv2 ) / 2.;
gp_Pnt xyz = surface->Value( uv.X(), uv.Y() );
- x = xyz.X(); y = xyz.Y(); z = xyz.Z();
+ x = xyz.X(); y = xyz.Y(); z = xyz.Z();
}
else {
x = (Ns[i]->X() + Ns[i+2]->X())/2;
}
}
}
-
+
} // loop on face ids
}
if ( nbSame == 0 ) // --- hexahedron
aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], prevNod[ 3 ],
nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ], nextNod[ 3 ]);
-
+
else if ( nbSame == 1 ) { // --- pyramid + pentahedron
aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ],
nextNod[ iAfterSame ], nextNod[ iBeforeSame ],
// realized for extrusion only
//vector<const SMDS_MeshNode*> polyedre_nodes (nbNodes*2 + 4*nbNodes);
//vector<int> quantities (nbNodes + 2);
-
+
//quantities[0] = nbNodes; // bottom of prism
//for (int inode = 0; inode < nbNodes; inode++) {
// polyedre_nodes[inode] = prevNod[inode];
//for (int inode = 0; inode < nbNodes; inode++) {
// polyedre_nodes[nbNodes + inode] = nextNod[inode];
//}
-
+
//for (int iface = 0; iface < nbNodes; iface++) {
// quantities[iface + 2] = 4;
// int inextface = (iface == nbNodes - 1) ? 0 : iface + 1;
//=======================================================================
//function : CreateNode
-//purpose :
+//purpose :
//=======================================================================
const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x,
const double y,
gp_Pnt P2(aN->X(),aN->Y(),aN->Z());
if(P1.Distance(P2)<tolnode)
return aN;
- }
+ }
}
// create new node and return it
if ( !theCopy && needReverse ) {
SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
while ( invElemIt->more() ) {
- const SMDS_MeshElement* iel = invElemIt->next();
+ const SMDS_MeshElement* iel = invElemIt->next();
inverseElemSet.insert( iel );
}
}
//=======================================================================
//function : FindCoincidentNodes
//purpose : Return list of group of nodes close to each other within theTolerance
-// Search among theNodes or in the whole mesh if theNodes is empty.
+// Search among theNodes or in the whole mesh if theNodes is empty using
+// an Octree algorithm
//=======================================================================
void SMESH_MeshEditor::FindCoincidentNodes (set<const SMDS_MeshNode*> & theNodes,
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
- double tol2 = theTolerance * theTolerance;
-
- list<const SMDS_MeshNode*> nodes;
+ set<const SMDS_MeshNode*> nodes;
if ( theNodes.empty() )
{ // get all nodes in the mesh
SMDS_NodeIteratorPtr nIt = GetMeshDS()->nodesIterator();
while ( nIt->more() )
- nodes.push_back( nIt->next() );
+ nodes.insert( nodes.end(),nIt->next());
}
else
- {
- nodes.insert( nodes.end(), theNodes.begin(), theNodes.end() );
- }
-
- list<const SMDS_MeshNode*>::iterator it2, it1 = nodes.begin();
- for ( ; it1 != nodes.end(); it1++ )
- {
- const SMDS_MeshNode* n1 = *it1;
- gp_Pnt p1( n1->X(), n1->Y(), n1->Z() );
+ nodes=theNodes;
+ SMESH_OctreeNode::FindCoincidentNodes ( nodes, &theGroupsOfNodes, theTolerance);
- list<const SMDS_MeshNode*> * groupPtr = 0;
- it2 = it1;
- for ( it2++; it2 != nodes.end(); it2++ )
- {
- const SMDS_MeshNode* n2 = *it2;
- gp_Pnt p2( n2->X(), n2->Y(), n2->Z() );
- if ( p1.SquareDistance( p2 ) <= tol2 )
- {
- if ( !groupPtr ) {
- theGroupsOfNodes.push_back( list<const SMDS_MeshNode*>() );
- groupPtr = & theGroupsOfNodes.back();
- groupPtr->push_back( n1 );
- }
- if(groupPtr->front()>n2)
- groupPtr->push_front( n2 );
- else
- groupPtr->push_back( n2 );
- it2 = nodes.erase( it2 );
- it2--;
- }
- }
- }
}
//=======================================================================
else
isOk = false;
break;
- case 8: {
+ case 8: {
if(elem->IsQuadratic()) { // Quadratic quadrangle
// 1 5 2
// +---+---+
}
}
}
-
+
// create new elements
SMESHDS_Mesh *aMesh = GetMeshDS();
int aShapeId = FindShape( theFace );
-
+
i1 = 0; i2 = 1;
for ( iSplit = 0; iSplit < nbSplits - 1; iSplit++ ) {
SMDS_MeshElement* newElem = 0;
if ( aShapeId && newElem )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
}
-
+
// change nodes of theFace
const SMDS_MeshNode* newNodes[ 4 ];
newNodes[ 0 ] = linkNodes[ i1 ];
il1 = il1 - nbshift;
// now have to insert nodes between n0 and n1 or n1 and n2 (see below)
// n0 n1 n2 n0 n1 n2
- // +-----+-----+ +-----+-----+
+ // +-----+-----+ +-----+-----+
// \ / | |
// \ / | |
// n5+ +n3 n7+ +n3
int id = elem->GetID();
int nbNodes = elem->NbNodes();
vector<const SMDS_MeshNode *> aNds (nbNodes);
-
+
for(int i = 0; i < nbNodes; i++)
{
aNds[i] = elem->GetNode(i);
{
case SMDSAbs_Edge :
{
- meshDS->RemoveFreeElement(elem, theSm);
+ meshDS->RemoveFreeElement(elem, theSm);
NewElem = theHelper->AddQuadraticEdge(aNds[0], aNds[1], id, theForce3d);
break;
}
default:
continue;
}
- break;
+ break;
}
case SMDSAbs_Volume :
{
default:
continue;
}
- break;
+ break;
}
default :
continue;
if ( !aShape.IsNull() && GetMesh()->GetSubMeshContaining(aShape) )
{
SMESH_subMesh *aSubMesh = GetMesh()->GetSubMeshContaining(aShape);
-
+
const map < int, SMESH_subMesh * >& aMapSM = aSubMesh->DependsOn();
map < int, SMESH_subMesh * >::const_iterator itsub;
for (itsub = aMapSM.begin(); itsub != aMapSM.end(); itsub++)
{
const SMDS_MeshFace* face = aFaceItr->next();
if(!face || face->IsQuadratic() ) continue;
-
+
int id = face->GetID();
int nbNodes = face->NbNodes();
vector<const SMDS_MeshNode *> aNds (nbNodes);
aNds[i] = face->GetNode(i);
}
- RemoveElemFromGroups (face, meshDS);
+ RemoveElemFromGroups (face, meshDS);
meshDS->SMDS_Mesh::RemoveFreeElement(face);
SMDS_MeshFace * NewFace = 0;
{
const SMDS_MeshVolume* volume = aVolumeItr->next();
if(!volume || volume->IsQuadratic() ) continue;
-
+
int id = volume->GetID();
int nbNodes = volume->NbNodes();
vector<const SMDS_MeshNode *> aNds (nbNodes);
//function : RemoveQuadElem
//purpose :
//=======================================================================
-void SMESH_MeshEditor::RemoveQuadElem(SMESHDS_SubMesh *theSm,
+void SMESH_MeshEditor::RemoveQuadElem(SMESHDS_SubMesh *theSm,
SMDS_ElemIteratorPtr theItr,
RemoveQuadNodeMap& theRemoveNodeMap)
{
{
if( !elem->IsQuadratic() )
continue;
-
+
int id = elem->GetID();
int nbNodes = elem->NbNodes(), idx = 0;
- vector<const SMDS_MeshNode *> aNds;
+ vector<const SMDS_MeshNode *> aNds;
for(int i = 0; i < nbNodes; i++)
{
theRemoveNodeMap.insert(RemoveQuadNodeMap::value_type( n,theSm ));
}
}
- else
+ else
aNds.push_back( n );
}
idx = aNds.size();
if( !idx ) continue;
- SMDSAbs_ElementType aType = elem->GetType();
+ SMDSAbs_ElementType aType = elem->GetType();
//remove old quadratic elements
meshDS->RemoveFreeElement( elem, theSm );
if ( !aShape.IsNull() && GetMesh()->GetSubMeshContaining(aShape) )
{
SMESH_subMesh *aSubMesh = GetMesh()->GetSubMeshContaining(aShape);
-
+
const map < int, SMESH_subMesh * >& aMapSM = aSubMesh->DependsOn();
map < int, SMESH_subMesh * >::const_iterator itsub;
for (itsub = aMapSM.begin(); itsub != aMapSM.end(); itsub++)
RemoveQuadElem( aSM, meshDS->elementsIterator(), aRemoveNodeMap );
}
- //remove all quadratic nodes
+ //remove all quadratic nodes
ItRemoveQuadNodeMap itRNM = aRemoveNodeMap.begin();
- for ( ; itRNM != aRemoveNodeMap.end(); itRNM++ )
+ for ( ; itRNM != aRemoveNodeMap.end(); itRNM++ )
{
- meshDS->RemoveFreeNode( (*itRNM).first, (*itRNM).second );
+ meshDS->RemoveFreeNode( (*itRNM).first, (*itRNM).second );
}
return true;
//================================================================================
/*!
- * \brief Find corresponding nodes in two sets of faces
+ * \brief Find corresponding nodes in two sets of faces
* \param theSide1 - first face set
* \param theSide2 - second first face
* \param theFirstNode1 - a boundary node of set 1