#include "SMESH_subMesh.hxx"
#include "SMESH_ControlsDef.hxx"
+#include "SMESH_MesherHelper.hxx"
#include "utilities.h"
#include <GeomAdaptor_Surface.hxx>
#include <ElCLib.hxx>
#include <TColStd_ListOfInteger.hxx>
+#include <TopoDS_Face.hxx>
#include <map>
bool SMESH_MeshEditor::Remove (const list< int >& theIDs,
const bool isNodes )
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
SMESHDS_Mesh* aMesh = GetMeshDS();
set< SMESH_subMesh *> smmap;
const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
const SMDS_PositionPtr& aPosition = node->GetPosition();
if ( aPosition.get() ) {
- int aShapeID = aPosition->GetShapeId();
- if ( aShapeID ) {
- TopoDS_Shape aShape = aMesh->IndexToShape( aShapeID );
- SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( aShape );
- if ( sm )
+ if ( int aShapeID = aPosition->GetShapeId() ) {
+ if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( aShapeID ) )
smmap.insert( sm );
}
}
(*smIt)->ComputeStateEngine( SMESH_subMesh::MESH_ENTITY_REMOVED );
}
+ // Check if the whole mesh becomes empty
+ if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( 1 ) )
+ sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+
return true;
}
int SMESH_MeshEditor::FindShape (const SMDS_MeshElement * theElem)
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
SMESHDS_Mesh * aMesh = GetMeshDS();
if ( aMesh->ShapeToMesh().IsNull() )
return 0;
bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1,
const SMDS_MeshElement * theTria2 )
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
if (!theTria1 || !theTria2)
return false;
if ( elem->GetType() == SMDSAbs_Face &&
emap.find( elem ) != emap.end() )
if ( theTria1 ) {
- theTria2 = elem;
+ // theTria1 must be element with minimum ID
+ if( theTria1->GetID() < elem->GetID() ) {
+ theTria2 = elem;
+ }
+ else {
+ theTria2 = theTria1;
+ theTria1 = elem;
+ }
break;
}
else {
bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshNode * theNode1,
const SMDS_MeshNode * theNode2)
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
MESSAGE( "::InverseDiag()" );
const SMDS_MeshElement *tr1, *tr2;
bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1,
const SMDS_MeshNode * theNode2)
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
MESSAGE( "::DeleteDiag()" );
const SMDS_MeshElement *tr1, *tr2;
//MESSAGE( endl << tr1 << tr2 );
GetMeshDS()->ChangeElementNodes( tr1, aNodes, 4 );
+ myLastCreatedElems.Append(tr1);
GetMeshDS()->RemoveElement( tr2 );
//MESSAGE( endl << tr1 );
aNodes[7] = N1[5];
GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
+ myLastCreatedElems.Append(tr1);
GetMeshDS()->RemoveElement( tr2 );
// remove middle node (9)
bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem)
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
if (!theElem)
return false;
SMDS_ElemIteratorPtr it = theElem->nodesIterator();
// theCrit is used to select a diagonal to cut
//=======================================================================
-bool SMESH_MeshEditor::QuadToTri (set<const SMDS_MeshElement*> & theElems,
+bool SMESH_MeshEditor::QuadToTri (map<int,const SMDS_MeshElement*> & theElems,
SMESH::Controls::NumericalFunctorPtr theCrit)
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
MESSAGE( "::QuadToTri()" );
if ( !theCrit.get() )
SMESHDS_Mesh * aMesh = GetMeshDS();
- set< const SMDS_MeshElement * >::iterator itElem;
+ Handle(Geom_Surface) surface;
+ SMESH_MesherHelper helper( *GetMesh() );
+
+ map<int, const SMDS_MeshElement * >::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
- const SMDS_MeshElement* elem = (*itElem);
+ const SMDS_MeshElement* elem = (*itElem).second;
if ( !elem || elem->GetType() != SMDSAbs_Face )
continue;
+ if ( elem->NbNodes() != ( elem->IsQuadratic() ? 8 : 4 ))
+ continue;
- if(elem->NbNodes()==4) {
+ // retrieve element nodes
+ const SMDS_MeshNode* aNodes [8];
+ SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+ int i = 0;
+ while ( itN->more() )
+ aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
- // retrieve element nodes
- const SMDS_MeshNode* aNodes [4];
- SMDS_ElemIteratorPtr itN = elem->nodesIterator();
- int i = 0;
- while ( itN->more() )
- aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+ // compare two sets of possible triangles
+ 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 );
- // compare two sets of possible triangles
- 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 );
+ 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 );
- //MESSAGE( "aBadRate1 = " << aBadRate1 << "; aBadRate2 = " << aBadRate2
- // << " ShapeID = " << aShapeId << endl << elem );
+ int aShapeId = FindShape( elem );
+ const SMDS_MeshElement* newElem = 0;
+
+ if( !elem->IsQuadratic() ) {
+
+ // split liner quadrangle
if ( aBadRate1 <= aBadRate2 ) {
// tr1 + tr2 is better
aMesh->ChangeElementNodes( elem, aNodes, 3 );
- //MESSAGE( endl << elem );
-
- elem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
+ newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
}
else {
// tr3 + tr4 is better
aMesh->ChangeElementNodes( elem, &aNodes[1], 3 );
- //MESSAGE( endl << elem );
-
- elem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
+ newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
}
- //MESSAGE( endl << 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;
+ if ( aShapeId > 0 )
+ 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* inFaceNode = 0;
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
int i = 0;
while ( itN->more() ) {
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)
- // and create node in this point;
- double x=0., y=0., z=0.;
- for(i=0; i<4; i++) {
- x += aNodes[i]->X();
- y += aNodes[i]->Y();
- z += aNodes[i]->Z();
+ // and create a node in this point;
+ gp_XYZ p( 0,0,0 );
+ if ( surface.IsNull() ) {
+ for(i=0; i<4; i++)
+ p += gp_XYZ(aNodes[i]->X(), aNodes[i]->Y(), 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);
+
+ // create a new element
+ const SMDS_MeshNode* N[6];
if ( aBadRate1 <= aBadRate2 ) {
- // tr1 + tr2 is better
- const SMDS_MeshNode* N[6];
N[0] = aNodes[0];
N[1] = aNodes[1];
N[2] = aNodes[2];
N[3] = aNodes[4];
N[4] = aNodes[5];
N[5] = newN;
- aMesh->ChangeElementNodes( elem, N, 6 );
- elem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
- aNodes[6], aNodes[7], newN );
+ newElem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
+ aNodes[6], aNodes[7], newN );
}
else {
- // tr3 + tr4 is better
- const SMDS_MeshNode* N[6];
N[0] = aNodes[1];
N[1] = aNodes[2];
N[2] = aNodes[3];
N[3] = aNodes[5];
N[4] = aNodes[6];
N[5] = newN;
- aMesh->ChangeElementNodes( elem, N, 6 );
- elem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
- aNodes[7], aNodes[4], newN );
- }
- // put a new triangle on the same shape
- if ( aShapeId ) {
- aMesh->SetMeshElementOnShape( elem, aShapeId );
+ newElem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
+ aNodes[7], aNodes[4], newN );
}
- }
+ aMesh->ChangeElementNodes( elem, N, 6 );
+
+ } // 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;
}
int SMESH_MeshEditor::BestSplit (const SMDS_MeshElement* theQuad,
SMESH::Controls::NumericalFunctorPtr theCrit)
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
if (!theCrit.get())
return -1;
}
}
+
+//=======================================================================
+//function : RemoveElemFromGroups
+//purpose : Remove removeelem to the groups the elemInGroups belongs to
+//=======================================================================
+void SMESH_MeshEditor::RemoveElemFromGroups (const SMDS_MeshElement* removeelem,
+ SMESHDS_Mesh * aMesh)
+{
+ const set<SMESHDS_GroupBase*>& groups = aMesh->GetGroups();
+ if (!groups.empty())
+ {
+ set<SMESHDS_GroupBase*>::const_iterator GrIt = groups.begin();
+ for (; GrIt != groups.end(); GrIt++)
+ {
+ SMESHDS_Group* grp = dynamic_cast<SMESHDS_Group*>(*GrIt);
+ if (!grp || grp->IsEmpty()) continue;
+ grp->SMDSGroup().Remove(removeelem);
+ }
+ }
+}
+
+
//=======================================================================
//function : QuadToTri
//purpose : Cut quadrangles into triangles.
// theCrit is used to select a diagonal to cut
//=======================================================================
-bool SMESH_MeshEditor::QuadToTri (std::set<const SMDS_MeshElement*> & theElems,
- const bool the13Diag)
+bool SMESH_MeshEditor::QuadToTri (std::map<int,const SMDS_MeshElement*> & theElems,
+ const bool the13Diag)
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
MESSAGE( "::QuadToTri()" );
SMESHDS_Mesh * aMesh = GetMeshDS();
- set< const SMDS_MeshElement * >::iterator itElem;
+ Handle(Geom_Surface) surface;
+ SMESH_MesherHelper helper( *GetMesh() );
+
+ map<int, const SMDS_MeshElement * >::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
- const SMDS_MeshElement* elem = (*itElem);
+ const SMDS_MeshElement* elem = (*itElem).second;
if ( !elem || elem->GetType() != SMDSAbs_Face )
continue;
bool isquad = elem->NbNodes()==4 || elem->NbNodes()==8;
aMesh->ChangeElementNodes( elem, &aNodes[1], 3 );
newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
}
+ myLastCreatedElems.Append(newElem);
// put a new triangle on the same shape and add to the same groups
if ( aShapeId )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
AddToSameGroups( newElem, elem, aMesh );
}
+ // Quadratic quadrangle
+
if( elem->NbNodes()==8 && elem->IsQuadratic() ) {
+
+ // get surface elem is on
+ int aShapeId = FindShape( elem );
+ if ( aShapeId != helper.GetSubShapeID() ) {
+ surface.Nullify();
+ TopoDS_Shape shape;
+ if ( aShapeId > 0 )
+ 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* inFaceNode = 0;
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
int i = 0;
while ( itN->more() ) {
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)
- // and create node in this point;
- double x=0., y=0., z=0.;
- for(i=0; i<4; i++) {
- x += aNodes[i]->X();
- y += aNodes[i]->Y();
- z += aNodes[i]->Z();
+ // and create a node in this point;
+ gp_XYZ p( 0,0,0 );
+ if ( surface.IsNull() ) {
+ for(i=0; i<4; i++)
+ p += gp_XYZ(aNodes[i]->X(), aNodes[i]->Y(), 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);
- int aShapeId = FindShape( elem );
+ // create a new element
const SMDS_MeshElement* newElem = 0;
+ const SMDS_MeshNode* N[6];
if ( the13Diag ) {
- const SMDS_MeshNode* N[6];
N[0] = aNodes[0];
N[1] = aNodes[1];
N[2] = aNodes[2];
N[3] = aNodes[4];
N[4] = aNodes[5];
N[5] = newN;
- aMesh->ChangeElementNodes( elem, N, 6 );
- elem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
- aNodes[6], aNodes[7], newN );
+ newElem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
+ aNodes[6], aNodes[7], newN );
}
else {
- const SMDS_MeshNode* N[6];
N[0] = aNodes[1];
N[1] = aNodes[2];
N[2] = aNodes[3];
N[3] = aNodes[5];
N[4] = aNodes[6];
N[5] = newN;
- aMesh->ChangeElementNodes( elem, N, 6 );
- elem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
- aNodes[7], aNodes[4], newN );
+ newElem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
+ aNodes[7], aNodes[4], newN );
}
+ myLastCreatedElems.Append(newElem);
+ aMesh->ChangeElementNodes( elem, N, 6 );
// put a new triangle on the same shape and add to the same groups
if ( aShapeId )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
// fusion is still performed.
//=======================================================================
-bool SMESH_MeshEditor::TriToQuad (set<const SMDS_MeshElement*> & theElems,
+bool SMESH_MeshEditor::TriToQuad (map<int,const SMDS_MeshElement*> & theElems,
SMESH::Controls::NumericalFunctorPtr theCrit,
const double theMaxAngle)
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
MESSAGE( "::TriToQuad()" );
if ( !theCrit.get() )
map< const SMDS_MeshElement*, set< NLink > > mapEl_setLi;
map< const SMDS_MeshElement*, set< NLink > >::iterator itEL;
- set<const SMDS_MeshElement*>::iterator itElem;
+ map<int,const SMDS_MeshElement*>::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
- const SMDS_MeshElement* elem = (*itElem);
+ const SMDS_MeshElement* elem = (*itElem).second;
//if ( !elem || elem->NbNodes() != 3 )
// continue;
if(!elem || elem->GetType() != SMDSAbs_Face ) continue;
mapEl_setLi.erase( tr2 );
mapLi_listEl.erase( link12 );
if(tr1->NbNodes()==3) {
- aMesh->ChangeElementNodes( tr1, n12, 4 );
- aMesh->RemoveElement( tr2 );
+ if( tr1->GetID() < tr2->GetID() ) {
+ aMesh->ChangeElementNodes( tr1, n12, 4 );
+ myLastCreatedElems.Append(tr1);
+ aMesh->RemoveElement( tr2 );
+ }
+ else {
+ aMesh->ChangeElementNodes( tr2, n12, 4 );
+ myLastCreatedElems.Append(tr2);
+ aMesh->RemoveElement( tr1);
+ }
}
else {
const SMDS_MeshNode* N1 [6];
aNodes[5] = N2[5];
aNodes[6] = N2[3];
aNodes[7] = N1[5];
- GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
- GetMeshDS()->RemoveElement( tr2 );
+ if( tr1->GetID() < tr2->GetID() ) {
+ GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
+ myLastCreatedElems.Append(tr1);
+ GetMeshDS()->RemoveElement( tr2 );
+ }
+ else {
+ GetMeshDS()->ChangeElementNodes( tr2, aNodes, 8 );
+ myLastCreatedElems.Append(tr2);
+ GetMeshDS()->RemoveElement( tr1 );
+ }
// remove middle node (9)
GetMeshDS()->RemoveNode( N1[4] );
}
mapEl_setLi.erase( tr3 );
mapLi_listEl.erase( link13 );
if(tr1->NbNodes()==3) {
- aMesh->ChangeElementNodes( tr1, n13, 4 );
- aMesh->RemoveElement( tr3 );
+ if( tr1->GetID() < tr2->GetID() ) {
+ aMesh->ChangeElementNodes( tr1, n13, 4 );
+ myLastCreatedElems.Append(tr1);
+ aMesh->RemoveElement( tr3 );
+ }
+ else {
+ aMesh->ChangeElementNodes( tr3, n13, 4 );
+ myLastCreatedElems.Append(tr3);
+ aMesh->RemoveElement( tr1 );
+ }
}
else {
const SMDS_MeshNode* N1 [6];
aNodes[5] = N2[5];
aNodes[6] = N2[3];
aNodes[7] = N1[5];
- GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
- GetMeshDS()->RemoveElement( tr3 );
+ if( tr1->GetID() < tr2->GetID() ) {
+ GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
+ myLastCreatedElems.Append(tr1);
+ GetMeshDS()->RemoveElement( tr3 );
+ }
+ else {
+ GetMeshDS()->ChangeElementNodes( tr3, aNodes, 8 );
+ myLastCreatedElems.Append(tr3);
+ GetMeshDS()->RemoveElement( tr1 );
+ }
// remove middle node (9)
GetMeshDS()->RemoveNode( N1[4] );
}
// on edges and boundary nodes are always fixed.
//=======================================================================
-void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
+void SMESH_MeshEditor::Smooth (map<int,const SMDS_MeshElement*> & theElems,
set<const SMDS_MeshNode*> & theFixedNodes,
const SmoothMethod theSmoothMethod,
const int theNbIterations,
double theTgtAspectRatio,
const bool the2D)
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
MESSAGE((theSmoothMethod==LAPLACIAN ? "LAPLACIAN" : "CENTROIDAL") << "--::Smooth()");
if ( theTgtAspectRatio < 1.0 )
if ( theElems.empty() ) {
// add all faces to theElems
SMDS_FaceIteratorPtr fIt = aMesh->facesIterator();
- while ( fIt->more() )
- theElems.insert( fIt->next() );
+ while ( fIt->more() ) {
+ const SMDS_MeshElement* face = fIt->next();
+ theElems.insert( make_pair(face->GetID(),face) );
+ }
}
// get all face ids theElems are on
set< int > faceIdSet;
- set< const SMDS_MeshElement* >::iterator itElem;
+ map<int, const SMDS_MeshElement* >::iterator itElem;
if ( the2D )
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
- int fId = FindShape( *itElem );
+ int fId = FindShape( (*itElem).second );
// check that corresponding submesh exists and a shape is face
if (fId &&
faceIdSet.find( fId ) == faceIdSet.end() &&
if ( faceSubMesh && nbElemOnFace == faceSubMesh->NbElements() )
break; // all elements found
- const SMDS_MeshElement* elem = (*itElem);
+ const SMDS_MeshElement* elem = (*itElem).second;
if ( !elem || elem->GetType() != SMDSAbs_Face || elem->NbNodes() < 3 ||
( faceSubMesh && !faceSubMesh->Contains( elem ))) {
++itElem;
// move medium nodes of quadratic elements
if ( isQuadratic )
{
+ SMESH_MesherHelper helper( *GetMesh() );
+ if ( !face.IsNull() )
+ helper.SetSubShape( face );
list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();
for ( ; elemIt != elemsOnFace.end(); ++elemIt ) {
const SMDS_QuadraticFaceOfNodes* QF =
while ( anIter->more() )
Ns.push_back( anIter->next() );
Ns.push_back( Ns[0] );
+ double x, y, z;
for(int i=0; i<QF->NbNodes(); i=i+2) {
- double x = (Ns[i]->X() + Ns[i+2]->X())/2;
- double y = (Ns[i]->Y() + Ns[i+2]->Y())/2;
- double z = (Ns[i]->Z() + Ns[i+2]->Z())/2;
+ if ( !surface.IsNull() ) {
+ gp_XY uv1 = helper.GetNodeUV( face, Ns[i], Ns[i+2] );
+ 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();
+ }
+ else {
+ x = (Ns[i]->X() + Ns[i+2]->X())/2;
+ y = (Ns[i]->Y() + Ns[i+2]->Y())/2;
+ z = (Ns[i]->Z() + Ns[i+2]->Z())/2;
+ }
if( fabs( Ns[i+1]->X() - x ) > disttol ||
fabs( Ns[i+1]->Y() - y ) > disttol ||
fabs( Ns[i+1]->Z() - z ) > disttol ) {
const SMDS_MeshElement* elem,
const vector<TNodeOfNodeListMapItr> & newNodesItVec,
list<const SMDS_MeshElement*>& newElems,
- const int nbSteps)
+ const int nbSteps,
+ SMESH_SequenceOfElemPtr& myLastCreatedElems)
{
// Loop on elem nodes:
// find new nodes and detect same nodes indices
if ( aNewElem ) {
newElems.push_back( aNewElem );
+ myLastCreatedElems.Append(aNewElem);
}
// set new prev nodes
TNodeOfNodeListMap & mapNewNodes,
TElemOfElemListMap & newElemsMap,
TElemOfVecOfNnlmiMap & elemNewNodesMap,
- set<const SMDS_MeshElement*>& elemSet,
- const int nbSteps)
+ map<int,const SMDS_MeshElement*>& elemSet,
+ const int nbSteps,
+ SMESH_SequenceOfElemPtr& myLastCreatedElems)
{
ASSERT( newElemsMap.size() == elemNewNodesMap.size() );
while ( eIt->more() && nbInitElems < 2 ) {
el = eIt->next();
//if ( elemSet.find( eIt->next() ) != elemSet.end() )
- if ( elemSet.find(el) != elemSet.end() )
+ if ( elemSet.find(el->GetID()) != elemSet.end() )
nbInitElems++;
}
if ( nbInitElems < 2 ) {
if(!NotCreateEdge) {
vector<TNodeOfNodeListMapItr> newNodesItVec( 1, nList );
list<const SMDS_MeshElement*> newEdges;
- sweepElement( aMesh, node, newNodesItVec, newEdges, nbSteps );
+ sweepElement( aMesh, node, newNodesItVec, newEdges, nbSteps, myLastCreatedElems );
}
}
}
if ( elem->GetType() == SMDSAbs_Edge ) {
if(!elem->IsQuadratic()) {
// create a ceiling edge
- aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
- vecNewNodes[ 1 ]->second.back() );
+ myLastCreatedElems.Append(aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
+ vecNewNodes[ 1 ]->second.back()));
}
else {
// create a ceiling edge
- aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
- vecNewNodes[ 1 ]->second.back(),
- vecNewNodes[ 2 ]->second.back());
+ myLastCreatedElems.Append(aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
+ vecNewNodes[ 1 ]->second.back(),
+ vecNewNodes[ 2 ]->second.back()));
}
}
if ( elem->GetType() != SMDSAbs_Face )
continue;
+ if(itElem->second.size()==0) continue;
+
bool hasFreeLinks = false;
- set<const SMDS_MeshElement*> avoidSet;
- avoidSet.insert( elem );
+ map<int,const SMDS_MeshElement*> avoidSet;
+ avoidSet.insert( make_pair(elem->GetID(),elem) );
set<const SMDS_MeshNode*> aFaceLastNodes;
int iNode, nbNodes = vecNewNodes.size();
hasFreeLinks = true;
// make an edge and a ceiling for a new edge
if ( !aMesh->FindEdge( n1, n2 )) {
- aMesh->AddEdge( n1, n2 );
+ myLastCreatedElems.Append(aMesh->AddEdge( n1, n2 ));
}
n1 = vecNewNodes[ iNode ]->second.back();
n2 = vecNewNodes[ iNext ]->second.back();
if ( !aMesh->FindEdge( n1, n2 )) {
- aMesh->AddEdge( n1, n2 );
+ myLastCreatedElems.Append(aMesh->AddEdge( n1, n2 ));
}
}
}
// find medium node
const SMDS_MeshNode* n3 = vecNewNodes[ iNode+nbn ]->first;
if ( !aMesh->FindEdge( n1, n2, n3 )) {
- aMesh->AddEdge( n1, n2, n3 );
+ myLastCreatedElems.Append(aMesh->AddEdge( n1, n2, n3 ));
}
n1 = vecNewNodes[ iNode ]->second.back();
n2 = vecNewNodes[ iNext ]->second.back();
n3 = vecNewNodes[ iNode+nbn ]->second.back();
if ( !aMesh->FindEdge( n1, n2, n3 )) {
- aMesh->AddEdge( n1, n2, n3 );
+ myLastCreatedElems.Append(aMesh->AddEdge( n1, n2, n3 ));
}
}
}
//switch ( vTool.NbFaceNodes( *ind ) ) {
switch ( nbn ) {
case 3:
- aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ); break;
+ myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] )); break;
case 4:
- aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] ); break;
+ myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] )); break;
default:
{
if( (*v)->IsQuadratic() ) {
if(nbn==6) {
- aMesh->AddFace(nodes[0], nodes[2], nodes[4],
- nodes[1], nodes[3], nodes[5]); break;
+ myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4],
+ nodes[1], nodes[3], nodes[5])); break;
}
else {
- aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6],
- nodes[1], nodes[3], nodes[5], nodes[7]);
+ myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6],
+ nodes[1], nodes[3], nodes[5], nodes[7]));
break;
}
}
for (int inode = 0; inode < nbPolygonNodes; inode++) {
polygon_nodes[inode] = nodes[inode];
}
- aMesh->AddPolygonalFace(polygon_nodes);
+ myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes));
}
break;
}
case 3:
if (!hasFreeLinks ||
!aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ]))
- aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] );
+ myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ));
break;
case 4:
if (!hasFreeLinks ||
!aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ]))
- aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] );
+ myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] ));
break;
default:
{
if (!hasFreeLinks ||
!aMesh->FindFace(nodes[0], nodes[2], nodes[4],
nodes[1], nodes[3], nodes[5]) ) {
- aMesh->AddFace(nodes[0], nodes[2], nodes[4],
- nodes[1], nodes[3], nodes[5]); break;
+ myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4],
+ nodes[1], nodes[3], nodes[5])); break;
}
}
else { // nbn==8
if (!hasFreeLinks ||
!aMesh->FindFace(nodes[0], nodes[2], nodes[4], nodes[6],
nodes[1], nodes[3], nodes[5], nodes[7]) )
- aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6],
- nodes[1], nodes[3], nodes[5], nodes[7]);
+ myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6],
+ nodes[1], nodes[3], nodes[5], nodes[7]));
}
}
else {
polygon_nodes[inode] = nodes[inode];
}
if (!hasFreeLinks || !aMesh->FindFace(polygon_nodes))
- aMesh->AddPolygonalFace(polygon_nodes);
+ myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes));
}
}
break;
//purpose :
//=======================================================================
-void SMESH_MeshEditor::RotationSweep(set<const SMDS_MeshElement*> & theElems,
+void SMESH_MeshEditor::RotationSweep(map<int,const SMDS_MeshElement*> & theElems,
const gp_Ax1& theAxis,
const double theAngle,
const int theNbSteps,
const double theTol)
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
MESSAGE( "RotationSweep()");
gp_Trsf aTrsf;
aTrsf.SetRotation( theAxis, theAngle );
TElemOfElemListMap newElemsMap;
// loop on theElems
- set< const SMDS_MeshElement* >::iterator itElem;
+ map<int, const SMDS_MeshElement* >::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
- const SMDS_MeshElement* elem = (*itElem);
+ const SMDS_MeshElement* elem = (*itElem).second;
if ( !elem )
continue;
vector<TNodeOfNodeListMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
aTrsf2.Transforms( coord[0], coord[1], coord[2] );
//aTrsf.Transforms( coord[0], coord[1], coord[2] );
newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+ myLastCreatedNodes.Append(newNode);
listNewNodes.push_back( newNode );
aTrsf2.Transforms( coord[0], coord[1], coord[2] );
//aTrsf.Transforms( coord[0], coord[1], coord[2] );
aTrsf.Transforms( coord[0], coord[1], coord[2] );
}
newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+ myLastCreatedNodes.Append(newNode);
}
listNewNodes.push_back( newNode );
}
for(int i = 0; i<theNbSteps; i++) {
aTrsf2.Transforms( coord[0], coord[1], coord[2] );
newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+ myLastCreatedNodes.Append(newNode);
listNewNodes.push_back( newNode );
aTrsf2.Transforms( coord[0], coord[1], coord[2] );
newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+ myLastCreatedNodes.Append(newNode);
listNewNodes.push_back( newNode );
}
}
newNodesItVec.push_back( nIt );
}
// make new elements
- sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], theNbSteps );
+ sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], theNbSteps, myLastCreatedElems );
}
- makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, theNbSteps );
+ makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, theNbSteps, myLastCreatedElems );
}
const double tolnode,
SMESH_SequenceOfNode& aNodes)
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
gp_Pnt P1(x,y,z);
SMESHDS_Mesh * aMesh = myMesh->GetMeshDS();
// create new node and return it
const SMDS_MeshNode* NewNode = aMesh->AddNode(x,y,z);
+ myLastCreatedNodes.Append(NewNode);
return NewNode;
}
//=======================================================================
void SMESH_MeshEditor::ExtrusionSweep
- (set<const SMDS_MeshElement*> & theElems,
+ (map<int,const SMDS_MeshElement*> & theElems,
const gp_Vec& theStep,
const int theNbSteps,
TElemOfElemListMap& newElemsMap,
//=======================================================================
void SMESH_MeshEditor::ExtrusionSweep
- (set<const SMDS_MeshElement*> & theElems,
+ (map<int,const SMDS_MeshElement*> & theElems,
ExtrusParam& theParams,
TElemOfElemListMap& newElemsMap,
const int theFlags,
const double theTolerance)
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
SMESHDS_Mesh* aMesh = GetMeshDS();
int nbsteps = theParams.mySteps->Length();
//TElemOfVecOfMapNodesMap mapElemNewNodes;
// loop on theElems
- set< const SMDS_MeshElement* >::iterator itElem;
+ map<int, const SMDS_MeshElement* >::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
// check element type
- const SMDS_MeshElement* elem = (*itElem);
+ const SMDS_MeshElement* elem = (*itElem).second;
if ( !elem )
continue;
}
else {
const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z);
+ myLastCreatedNodes.Append(newNode);
listNewNodes.push_back( newNode );
}
}
}
else {
const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+ myLastCreatedNodes.Append(newNode);
listNewNodes.push_back( newNode );
//vecNewNodes[i]=newNode;
}
}
else {
const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z);
+ myLastCreatedNodes.Append(newNode);
listNewNodes.push_back( newNode );
}
coord[0] = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1);
}
else {
const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+ myLastCreatedNodes.Append(newNode);
listNewNodes.push_back( newNode );
}
}
newNodesItVec.push_back( nIt );
}
// make new elements
- sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], nbsteps );
+ sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], nbsteps, myLastCreatedElems );
}
+
if( theFlags & EXTRUSION_FLAG_BOUNDARY ) {
- makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, nbsteps );
+ makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, nbsteps, myLastCreatedElems );
}
}
//purpose :
//=======================================================================
SMESH_MeshEditor::Extrusion_Error
- SMESH_MeshEditor::ExtrusionAlongTrack (std::set<const SMDS_MeshElement*> & theElements,
+ SMESH_MeshEditor::ExtrusionAlongTrack (std::map<int,const SMDS_MeshElement*> & theElements,
SMESH_subMesh* theTrack,
const SMDS_MeshNode* theN1,
const bool theHasAngles,
const bool theHasRefPoint,
const gp_Pnt& theRefPoint)
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
MESSAGE("SMESH_MeshEditor::ExtrusionAlongTrack")
int j, aNbTP, aNbE, aNb;
double aT1, aT2, aT, aAngle, aX, aY, aZ;
std::list<double> aPrms;
std::list<double>::iterator aItD;
- std::set< const SMDS_MeshElement* >::iterator itElem;
+ std::map<int, const SMDS_MeshElement* >::iterator itElem;
Standard_Real aTx1, aTx2, aL2, aTolVec, aTolVec2;
gp_Pnt aP3D, aV0;
itElem = theElements.begin();
for ( ; itElem != theElements.end(); itElem++ ) {
- const SMDS_MeshElement* elem = (*itElem);
+ const SMDS_MeshElement* elem = (*itElem).second;
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
while ( itN->more() ) {
for ( itElem = theElements.begin(); itElem != theElements.end(); itElem++ ) {
// check element type
- const SMDS_MeshElement* elem = (*itElem);
+ const SMDS_MeshElement* elem = (*itElem).second;
aTypeE = elem->GetType();
if ( !elem || ( aTypeE != SMDSAbs_Face && aTypeE != SMDSAbs_Edge ) )
continue;
double y = ( aPN1.Y() + aPN0.Y() )/2.;
double z = ( aPN1.Z() + aPN0.Z() )/2.;
const SMDS_MeshNode* newNode = aMesh->AddNode(x,y,z);
+ myLastCreatedNodes.Append(newNode);
listNewNodes.push_back( newNode );
}
aX = aPN1.X();
aY = aPN1.Y();
aZ = aPN1.Z();
const SMDS_MeshNode* newNode = aMesh->AddNode( aX, aY, aZ );
+ myLastCreatedNodes.Append(newNode);
listNewNodes.push_back( newNode );
aPN0 = aPN1;
double y = ( N->Y() + P.Y() )/2.;
double z = ( N->Z() + P.Z() )/2.;
const SMDS_MeshNode* newN = aMesh->AddNode(x,y,z);
+ myLastCreatedNodes.Append(newN);
aNodes[2*i] = newN;
aNodes[2*i+1] = N;
P = gp_XYZ(N->X(),N->Y(),N->Z());
newNodesItVec.push_back( nIt );
}
// make new elements
+ //sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem],
+ // newNodesItVec[0]->second.size(), myLastCreatedElems );
sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem],
- newNodesItVec[0]->second.size() );
+ aNbTP-1, myLastCreatedElems );
}
makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElements,
- aNbTP-1 );
+ aNbTP-1, myLastCreatedElems );
return EXTR_OK;
}
//purpose :
//=======================================================================
-void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
+void SMESH_MeshEditor::Transform (map<int,const SMDS_MeshElement*> & theElems,
const gp_Trsf& theTrsf,
const bool theCopy)
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
bool needReverse;
switch ( theTrsf.Form() ) {
case gp_PntMirror:
// elements sharing moved nodes; those of them which have all
// nodes mirrored but are not in theElems are to be reversed
- set<const SMDS_MeshElement*> inverseElemSet;
+ map<int,const SMDS_MeshElement*> inverseElemSet;
// loop on theElems
- set< const SMDS_MeshElement* >::iterator itElem;
+ map<int, const SMDS_MeshElement* >::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
- const SMDS_MeshElement* elem = (*itElem);
+ const SMDS_MeshElement* elem = (*itElem).second;
if ( !elem )
continue;
coord[2] = node->Z();
theTrsf.Transforms( coord[0], coord[1], coord[2] );
const SMDS_MeshNode * newNode = node;
- if ( theCopy )
+ if ( theCopy ) {
newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+ myLastCreatedNodes.Append(newNode);
+ }
else {
aMesh->MoveNode( node, coord[0], coord[1], coord[2] );
// node position on shape becomes invalid
// keep inverse elements
if ( !theCopy && needReverse ) {
SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
- while ( invElemIt->more() )
- inverseElemSet.insert( invElemIt->next() );
+ while ( invElemIt->more() ) {
+ const SMDS_MeshElement* iel = invElemIt->next();
+ inverseElemSet.insert( make_pair(iel->GetID(),iel) );
+ }
}
}
}
return;
if ( !inverseElemSet.empty()) {
- set<const SMDS_MeshElement*>::iterator invElemIt = inverseElemSet.begin();
+ map<int,const SMDS_MeshElement*>::iterator invElemIt = inverseElemSet.begin();
for ( ; invElemIt != inverseElemSet.end(); invElemIt++ )
theElems.insert( *invElemIt );
}
};
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
- const SMDS_MeshElement* elem = (*itElem);
+ const SMDS_MeshElement* elem = (*itElem).second;
if ( !elem || elem->GetType() == SMDSAbs_Node )
continue;
continue; // not all nodes transformed
if ( theCopy ) {
- aMesh->AddPolygonalFace(poly_nodes);
- } else {
+ myLastCreatedElems.Append(aMesh->AddPolygonalFace(poly_nodes));
+ }
+ else {
aMesh->ChangePolygonNodes(elem, poly_nodes);
}
}
continue; // not all nodes transformed
if ( theCopy ) {
- aMesh->AddPolyhedralVolume(poly_nodes, quantities);
- } else {
+ myLastCreatedElems.Append(aMesh->AddPolyhedralVolume(poly_nodes, quantities));
+ }
+ else {
aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
}
}
switch ( elemType ) {
case SMDSAbs_Edge:
if ( nbNodes == 2 )
- aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ] );
+ myLastCreatedElems.Append(aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ] ));
else
- aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] );
+ myLastCreatedElems.Append(aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ));
break;
case SMDSAbs_Face:
if ( nbNodes == 3 )
- aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] );
+ myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ));
else if(nbNodes==4)
- aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ]);
+ myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ]));
else if(nbNodes==6)
- aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
- nodes[4], nodes[5]);
+ myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
+ nodes[4], nodes[5]));
else // nbNodes==8
- aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
- nodes[4], nodes[5], nodes[6], nodes[7]);
+ myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
+ nodes[4], nodes[5], nodes[6], nodes[7]));
break;
case SMDSAbs_Volume:
if ( nbNodes == 4 )
- aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ] );
+ myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ] ));
else if ( nbNodes == 8 )
- aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
- nodes[ 4 ], nodes[ 5 ], nodes[ 6 ] , nodes[ 7 ]);
+ myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
+ nodes[ 4 ], nodes[ 5 ], nodes[ 6 ] , nodes[ 7 ]));
else if ( nbNodes == 6 )
- aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
- nodes[ 4 ], nodes[ 5 ]);
+ myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
+ nodes[ 4 ], nodes[ 5 ]));
else if ( nbNodes == 5 )
- aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
- nodes[ 4 ]);
+ myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
+ nodes[ 4 ]));
else if(nbNodes==10)
- aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
- nodes[5], nodes[6], nodes[7], nodes[8], nodes[9]);
+ myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
+ nodes[5], nodes[6], nodes[7], nodes[8], nodes[9]));
else if(nbNodes==13)
- aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
- nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
- nodes[10], nodes[11], nodes[12]);
+ myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
+ nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
+ nodes[10], nodes[11], nodes[12]));
else if(nbNodes==15)
- aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
- nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
- nodes[10], nodes[11], nodes[12], nodes[13], nodes[14]);
+ myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
+ nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
+ nodes[10], nodes[11], nodes[12], nodes[13], nodes[14]));
else // nbNodes==20
- aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
- nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
- nodes[10], nodes[11], nodes[12], nodes[13], nodes[14],
- nodes[15], nodes[16], nodes[17], nodes[18], nodes[19]);
+ myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
+ nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
+ nodes[10], nodes[11], nodes[12], nodes[13], nodes[14],
+ nodes[15], nodes[16], nodes[17], nodes[18], nodes[19]));
break;
default:;
}
const double theTolerance,
TListOfListOfNodes & theGroupsOfNodes)
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
double tol2 = theTolerance * theTolerance;
list<const SMDS_MeshNode*> nodes;
groupPtr = & theGroupsOfNodes.back();
groupPtr->push_back( n1 );
}
- groupPtr->push_back( n2 );
+ if(groupPtr->front()>n2)
+ groupPtr->push_front( n2 );
+ else
+ groupPtr->push_back( n2 );
it2 = nodes.erase( it2 );
it2--;
}
void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
SMESHDS_Mesh* aMesh = GetMeshDS();
TNodeNodeMap nodeNodeMap; // node to replace - new node
poly_nodes[ii] = polygons_nodes[inode];
}
SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes);
+ myLastCreatedElems.Append(newElem);
if (aShapeId)
aMesh->SetMeshElementOnShape(newElem, aShapeId);
}
curNodes[ 4 ],
curNodes[ 5 ],
curNodes[ iRepl[ 0 ] == 2 ? 1 : 2 ]);
+ myLastCreatedElems.Append(newElem);
if ( aShapeId )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
// 2. : reverse a bottom
curNodes[ind[ 3 ]],
curNodes[ind[ 2 ]],
curNodes[indTop[ 0 ]]);
+ myLastCreatedElems.Append(newElem);
if ( aShapeId )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
isOk = true;
curNodes[ i2 ],
curNodes[ i3d ],
curNodes[ i2t ]);
+ myLastCreatedElems.Append(newElem);
if ( aShapeId )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
isOk = true;
}
+
+// =================================================
+// class : SortableElement
+// purpose : auxilary
+// =================================================
+class SortableElement : public set <const SMDS_MeshElement*>
+{
+ public:
+
+ SortableElement( const SMDS_MeshElement* theElem )
+ {
+ myID = theElem->GetID();
+ SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator();
+ while ( nodeIt->more() )
+ this->insert( nodeIt->next() );
+ }
+
+ const long GetID() const
+ { return myID; }
+
+ void SetID(const long anID) const
+ { myID = anID; }
+
+
+ private:
+ mutable long myID;
+};
+
+
//=======================================================================
//function : MergeEqualElements
//purpose : Remove all but one of elements built on the same nodes.
void SMESH_MeshEditor::MergeEqualElements()
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
SMESHDS_Mesh* aMesh = GetMeshDS();
SMDS_EdgeIteratorPtr eIt = aMesh->edgesIterator();
for ( int iDim = 1; iDim <= 3; iDim++ ) {
- set< set <const SMDS_MeshElement*> > setOfNodeSet;
-
+ set< SortableElement > setOfNodeSet;
while ( 1 ) {
// get next element
const SMDS_MeshElement* elem = 0;
}
if ( !elem ) break;
- // get elem nodes
- set <const SMDS_MeshElement*> nodeSet;
- SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
- while ( nodeIt->more() )
- nodeSet.insert( nodeIt->next() );
+ SortableElement SE(elem);
// check uniqueness
- bool isUnique = setOfNodeSet.insert( nodeSet ).second;
- if ( !isUnique )
- rmElemIds.push_back( elem->GetID() );
+ pair< set<SortableElement>::iterator, bool> pp = setOfNodeSet.insert(SE);
+ if( !(pp.second) ) {
+ set<SortableElement>::iterator itSE = pp.first;
+ SortableElement SEold = *itSE;
+ if( SEold.GetID() > SE.GetID() ) {
+ rmElemIds.push_back( SEold.GetID() );
+ (*itSE).SetID(SE.GetID());
+ }
+ else {
+ rmElemIds.push_back( SE.GetID() );
+ }
+ }
}
}
const SMDS_MeshElement*
SMESH_MeshEditor::FindFaceInSet(const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2,
- const set<const SMDS_MeshElement*>& elemSet,
- const set<const SMDS_MeshElement*>& avoidSet)
+ const map<int,const SMDS_MeshElement*>& elemSet,
+ const map<int,const SMDS_MeshElement*>& avoidSet)
{
SMDS_ElemIteratorPtr invElemIt = n1->GetInverseElementIterator();
while ( invElemIt->more() ) { // loop on inverse elements of n1
const SMDS_MeshElement* elem = invElemIt->next();
if (elem->GetType() != SMDSAbs_Face ||
- avoidSet.find( elem ) != avoidSet.end() )
+ avoidSet.find( elem->GetID() ) != avoidSet.end() )
continue;
- if ( !elemSet.empty() && elemSet.find( elem ) == elemSet.end())
+ if ( !elemSet.empty() && elemSet.find( elem->GetID() ) == elemSet.end())
continue;
// get face nodes and find index of n1
int i1, nbN = elem->NbNodes(), iNode = 0;
const SMDS_QuadraticFaceOfNodes* F =
static_cast<const SMDS_QuadraticFaceOfNodes*>(elem);
// use special nodes iterator
+ iNode = 0;
SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
while ( anIter->more() ) {
faceNodes[iNode] = static_cast<const SMDS_MeshNode*>(anIter->next());
const SMDS_MeshNode* n2,
const SMDS_MeshElement* elem)
{
- set<const SMDS_MeshElement*> elemSet, avoidSet;
+ map<int,const SMDS_MeshElement*> elemSet, avoidSet;
if ( elem )
- avoidSet.insert ( elem );
+ avoidSet.insert ( make_pair(elem->GetID(),elem) );
return SMESH_MeshEditor::FindFaceInSet( n1, n2, elemSet, avoidSet );
}
const bool toCreatePolygons,
const bool toCreatePolyedrs)
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
MESSAGE("::SewFreeBorder()");
Sew_Error aResult = SEW_OK;
int aShapeId = FindShape( theFace );
SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes);
+ myLastCreatedElems.Append(newElem);
if ( aShapeId && newElem )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
newElem = aMesh->AddFace (linkNodes[ i1++ ],
linkNodes[ i2++ ],
nodes[ iSplit < iBestQuad ? i4 : i3 ]);
+ myLastCreatedElems.Append(newElem);
if ( aShapeId && newElem )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
}
if(nbFaceNodes==6) { // quadratic triangle
SMDS_MeshElement* newElem =
aMesh->AddFace(nodes[3],nodes[4],nodes[5]);
+ myLastCreatedElems.Append(newElem);
if ( aShapeId && newElem )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
if(theFace->IsMediumNode(nodes[il1])) {
// create quadrangle
newElem = aMesh->AddFace(nodes[0],nodes[1],nodes[3],nodes[5]);
+ myLastCreatedElems.Append(newElem);
if ( aShapeId && newElem )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
n1 = 1;
else {
// create quadrangle
newElem = aMesh->AddFace(nodes[1],nodes[2],nodes[3],nodes[5]);
+ myLastCreatedElems.Append(newElem);
if ( aShapeId && newElem )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
n1 = 0;
else { // nbFaceNodes==8 - quadratic quadrangle
SMDS_MeshElement* newElem =
aMesh->AddFace(nodes[3],nodes[4],nodes[5]);
+ myLastCreatedElems.Append(newElem);
if ( aShapeId && newElem )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
newElem = aMesh->AddFace(nodes[5],nodes[6],nodes[7]);
+ myLastCreatedElems.Append(newElem);
if ( aShapeId && newElem )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
newElem = aMesh->AddFace(nodes[5],nodes[7],nodes[3]);
+ myLastCreatedElems.Append(newElem);
if ( aShapeId && newElem )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
if(theFace->IsMediumNode(nodes[il1])) {
// create quadrangle
newElem = aMesh->AddFace(nodes[0],nodes[1],nodes[3],nodes[7]);
+ myLastCreatedElems.Append(newElem);
if ( aShapeId && newElem )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
n1 = 1;
else {
// create quadrangle
newElem = aMesh->AddFace(nodes[1],nodes[2],nodes[3],nodes[7]);
+ myLastCreatedElems.Append(newElem);
if ( aShapeId && newElem )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
n1 = 0;
for(i=1; i<nbn; i++) {
SMDS_MeshElement* newElem =
aMesh->AddFace(aNodes[i-1],aNodes[i],nodes[n3]);
+ myLastCreatedElems.Append(newElem);
if ( aShapeId && newElem )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
}
const SMDS_MeshNode* theBetweenNode2,
list<const SMDS_MeshNode*>& theNodesToInsert)
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
SMDS_ElemIteratorPtr invElemIt = theBetweenNode1->GetInverseElementIterator();
while (invElemIt->more()) { // loop on inverse elements of theBetweenNode1
const SMDS_MeshElement* elem = invElemIt->next();
SMDS_MeshElement* newElem =
aMesh->AddPolyhedralVolume(poly_nodes, quantities);
+ myLastCreatedElems.Append(newElem);
if (aShapeId && newElem)
aMesh->SetMeshElementOnShape(newElem, aShapeId);
}
}
+//=======================================================================
+//function : ConvertElemToQuadratic
+//purpose :
+//=======================================================================
+void SMESH_MeshEditor::ConvertElemToQuadratic(SMESHDS_SubMesh *theSm,
+ SMESH_MesherHelper* theHelper,
+ const bool theForce3d)
+{
+ if( !theSm ) return;
+ SMESHDS_Mesh* meshDS = GetMeshDS();
+ SMDS_ElemIteratorPtr ElemItr = theSm->GetElements();
+ while(ElemItr->more())
+ {
+ const SMDS_MeshElement* elem = ElemItr->next();
+ if( !elem ) continue;
+
+ 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);
+ }
+
+ SMDSAbs_ElementType aType = elem->GetType();
+ const SMDS_MeshElement* NewElem = 0;
+
+ switch( aType )
+ {
+ case SMDSAbs_Edge :
+ {
+ meshDS->RemoveFreeElement(elem, theSm);
+ NewElem = theHelper->AddQuadraticEdge(aNds[0], aNds[1], id, theForce3d);
+ break;
+ }
+ case SMDSAbs_Face :
+ {
+ if(elem->IsQuadratic()) continue;
+
+ meshDS->RemoveFreeElement(elem, theSm);
+ switch(nbNodes)
+ {
+ case 3:
+ NewElem = theHelper->AddFace(aNds[0], aNds[1], aNds[2], id, theForce3d);
+ break;
+ case 4:
+ NewElem = theHelper->AddFace(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d);
+ break;
+ default:
+ continue;
+ }
+ break;
+ }
+ case SMDSAbs_Volume :
+ {
+ if( elem->IsQuadratic() ) continue;
+
+ meshDS->RemoveFreeElement(elem, theSm);
+ switch(nbNodes)
+ {
+ case 4:
+ NewElem = theHelper->AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], id, true);
+ break;
+ case 6:
+ NewElem = theHelper->AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], aNds[4], aNds[5], id, true);
+ break;
+ case 8:
+ NewElem = theHelper->AddVolume(aNds[0], aNds[1], aNds[2], aNds[3],
+ aNds[4], aNds[5], aNds[6], aNds[7], id, true);
+ break;
+ default:
+ continue;
+ }
+ break;
+ }
+ default :
+ continue;
+ }
+ if( NewElem )
+ {
+ AddToSameGroups( NewElem, elem, meshDS);
+ theSm->AddElement( NewElem );
+ }
+ }
+}
+
+//=======================================================================
+//function : ConvertToQuadratic
+//purpose :
+//=======================================================================
+void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
+{
+ SMESHDS_Mesh* meshDS = GetMeshDS();
+
+ SMESH_MesherHelper* aHelper = new SMESH_MesherHelper(*myMesh);
+ aHelper->SetKeyIsQuadratic( true );
+ const TopoDS_Shape& aShape = meshDS->ShapeToMesh();
+
+ 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++)
+ {
+ SMESHDS_SubMesh *sm = ((*itsub).second)->GetSubMeshDS();
+ aHelper->SetSubShape( (*itsub).second->GetSubShape() );
+ ConvertElemToQuadratic(sm, aHelper, theForce3d);
+ }
+ aHelper->SetSubShape( aSubMesh->GetSubShape() );
+ ConvertElemToQuadratic(aSubMesh->GetSubMeshDS(), aHelper, theForce3d);
+ }
+ else
+ {
+ SMDS_EdgeIteratorPtr aEdgeItr = meshDS->edgesIterator();
+ while(aEdgeItr->more())
+ {
+ const SMDS_MeshEdge* edge = aEdgeItr->next();
+ if(edge)
+ {
+ int id = edge->GetID();
+ const SMDS_MeshNode* n1 = edge->GetNode(0);
+ const SMDS_MeshNode* n2 = edge->GetNode(1);
+
+ RemoveElemFromGroups (edge, meshDS);
+ meshDS->SMDS_Mesh::RemoveFreeElement(edge);
+
+ const SMDS_QuadraticEdge* NewEdge = aHelper->AddQuadraticEdge(n1, n2, id, theForce3d);
+ AddToSameGroups(NewEdge, edge, meshDS);
+ }
+ }
+ SMDS_FaceIteratorPtr aFaceItr = meshDS->facesIterator();
+ while(aFaceItr->more())
+ {
+ 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);
+
+ for(int i = 0; i < nbNodes; i++)
+ {
+ aNds[i] = face->GetNode(i);
+ }
+
+ RemoveElemFromGroups (face, meshDS);
+ meshDS->SMDS_Mesh::RemoveFreeElement(face);
+
+ SMDS_MeshFace * NewFace = 0;
+ switch(nbNodes)
+ {
+ case 3:
+ NewFace = aHelper->AddFace(aNds[0], aNds[1], aNds[2], id, theForce3d);
+ break;
+ case 4:
+ NewFace = aHelper->AddFace(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d);
+ break;
+ default:
+ continue;
+ }
+ AddToSameGroups(NewFace, face, meshDS);
+ }
+ SMDS_VolumeIteratorPtr aVolumeItr = meshDS->volumesIterator();
+ while(aVolumeItr->more())
+ {
+ 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);
+
+ for(int i = 0; i < nbNodes; i++)
+ {
+ aNds[i] = volume->GetNode(i);
+ }
+
+ RemoveElemFromGroups (volume, meshDS);
+ meshDS->SMDS_Mesh::RemoveFreeElement(volume);
+
+ SMDS_MeshVolume * NewVolume = 0;
+ switch(nbNodes)
+ {
+ case 4:
+ NewVolume = aHelper->AddVolume(aNds[0], aNds[1], aNds[2],
+ aNds[3], id, true );
+ break;
+ case 6:
+ NewVolume = aHelper->AddVolume(aNds[0], aNds[1], aNds[2],
+ aNds[3], aNds[4], aNds[5], id, true);
+ break;
+ case 8:
+ NewVolume = aHelper->AddVolume(aNds[0], aNds[1], aNds[2], aNds[3],
+ aNds[4], aNds[5], aNds[6], aNds[7], id, true);
+ break;
+ default:
+ continue;
+ }
+ AddToSameGroups(NewVolume, volume, meshDS);
+ }
+ }
+ delete aHelper;
+}
+
+//=======================================================================
+//function : RemoveQuadElem
+//purpose :
+//=======================================================================
+void SMESH_MeshEditor::RemoveQuadElem(SMESHDS_SubMesh *theSm,
+ SMDS_ElemIteratorPtr theItr,
+ RemoveQuadNodeMap& theRemoveNodeMap)
+{
+ SMESHDS_Mesh* meshDS = GetMeshDS();
+ while( theItr->more() )
+ {
+ const SMDS_MeshElement* elem = theItr->next();
+ if( elem )
+ {
+ if( !elem->IsQuadratic() )
+ continue;
+
+ int id = elem->GetID();
+
+ int nbNodes = elem->NbNodes(), idx = 0;
+ vector<const SMDS_MeshNode *> aNds;
+
+ for(int i = 0; i < nbNodes; i++)
+ {
+ const SMDS_MeshNode* n = elem->GetNode(i);
+
+ if( elem->IsMediumNode( n ) )
+ {
+ ItRemoveQuadNodeMap itRNM = theRemoveNodeMap.find( n );
+ if( itRNM == theRemoveNodeMap.end() )
+ {
+ theRemoveNodeMap.insert(RemoveQuadNodeMap::value_type( n,theSm ));
+ }
+ }
+ else
+ aNds.push_back( n );
+ }
+
+ idx = aNds.size();
+ if( !idx ) continue;
+ SMDSAbs_ElementType aType = elem->GetType();
+
+ //remove old quadratic elements
+ meshDS->RemoveFreeElement( elem, theSm );
+
+ SMDS_MeshElement * NewElem = 0;
+ switch(aType)
+ {
+ case SMDSAbs_Edge:
+ NewElem = meshDS->AddEdgeWithID( aNds[0], aNds[1] ,id );
+ break;
+ case SMDSAbs_Face:
+ if( idx==3 ) NewElem = meshDS->AddFaceWithID( aNds[0],
+ aNds[1], aNds[2], id );
+ if( idx==4 ) NewElem = meshDS->AddFaceWithID( aNds[0],
+ aNds[1], aNds[2], aNds[3],id );
+ break;
+ case SMDSAbs_Volume:
+ if( idx==4 ) NewElem = meshDS->AddVolumeWithID( aNds[0],
+ aNds[1], aNds[2], aNds[3], id );
+ if( idx==6 ) NewElem = meshDS->AddVolumeWithID( aNds[0],
+ aNds[1], aNds[2], aNds[3],
+ aNds[4], aNds[5], id );
+ if( idx==8 ) NewElem = meshDS->AddVolumeWithID(aNds[0],
+ aNds[1], aNds[2], aNds[3],
+ aNds[4], aNds[5], aNds[6],
+ aNds[7] ,id );
+ break;
+ default:
+ break;
+ }
+
+ AddToSameGroups(NewElem, elem, meshDS);
+ if( theSm )
+ theSm->AddElement( NewElem );
+ }
+ }
+}
+//=======================================================================
+//function : ConvertFromQuadratic
+//purpose :
+//=======================================================================
+bool SMESH_MeshEditor::ConvertFromQuadratic()
+{
+ SMESHDS_Mesh* meshDS = GetMeshDS();
+ RemoveQuadNodeMap aRemoveNodeMap;
+
+ const TopoDS_Shape& aShape = meshDS->ShapeToMesh();
+
+ 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++)
+ {
+ SMESHDS_SubMesh *sm = ((*itsub).second)->GetSubMeshDS();
+ if( sm )
+ RemoveQuadElem( sm, sm->GetElements(), aRemoveNodeMap );
+ }
+ SMESHDS_SubMesh *Sm = aSubMesh->GetSubMeshDS();
+ if( Sm )
+ RemoveQuadElem( Sm, Sm->GetElements(), aRemoveNodeMap );
+ }
+ else
+ {
+ SMESHDS_SubMesh *aSM = 0;
+ RemoveQuadElem( aSM, meshDS->elementsIterator(), aRemoveNodeMap );
+ }
+
+ //remove all quadratic nodes
+ ItRemoveQuadNodeMap itRNM = aRemoveNodeMap.begin();
+ for ( ; itRNM != aRemoveNodeMap.end(); itRNM++ )
+ {
+ meshDS->RemoveFreeNode( (*itRNM).first, (*itRNM).second );
+ }
+
+ return true;
+}
+
//=======================================================================
//function : SewSideElements
//purpose :
//=======================================================================
SMESH_MeshEditor::Sew_Error
- SMESH_MeshEditor::SewSideElements (set<const SMDS_MeshElement*>& theSide1,
- set<const SMDS_MeshElement*>& theSide2,
+ SMESH_MeshEditor::SewSideElements (map<int,const SMDS_MeshElement*>& theSide1,
+ map<int,const SMDS_MeshElement*>& theSide2,
const SMDS_MeshNode* theFirstNode1,
const SMDS_MeshNode* theFirstNode2,
const SMDS_MeshNode* theSecondNode1,
const SMDS_MeshNode* theSecondNode2)
{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
MESSAGE ("::::SewSideElements()");
if ( theSide1.size() != theSide2.size() )
return SEW_DIFF_NB_OF_ELEMENTS;
set<const SMDS_MeshElement*> * faceSetPtr[] = { &faceSet1, &faceSet2 };
set<const SMDS_MeshElement*> * volSetPtr[] = { &volSet1, &volSet2 };
set<const SMDS_MeshNode*> * nodeSetPtr[] = { &nodeSet1, &nodeSet2 };
- set<const SMDS_MeshElement*> * elemSetPtr[] = { &theSide1, &theSide2 };
+ map<int,const SMDS_MeshElement*> * elemSetPtr[] = { &theSide1, &theSide2 };
int iSide, iFace, iNode;
for ( iSide = 0; iSide < 2; iSide++ ) {
set<const SMDS_MeshNode*> * nodeSet = nodeSetPtr[ iSide ];
- set<const SMDS_MeshElement*> * elemSet = elemSetPtr[ iSide ];
+ map<int,const SMDS_MeshElement*> * elemSet = elemSetPtr[ iSide ];
set<const SMDS_MeshElement*> * faceSet = faceSetPtr[ iSide ];
set<const SMDS_MeshElement*> * volSet = volSetPtr [ iSide ];
- set<const SMDS_MeshElement*>::iterator vIt, eIt;
+ set<const SMDS_MeshElement*>::iterator vIt;
+ map<int,const SMDS_MeshElement*>::iterator eIt;
set<const SMDS_MeshNode*>::iterator nIt;
- // -----------------------------------------------------------
- // 1a. Collect nodes of existing faces
- // and build set of face nodes in order to detect missing
- // faces corresponing to sides of volumes
- // -----------------------------------------------------------
+ // check that given nodes belong to given elements
+ const SMDS_MeshNode* n1 = ( iSide == 0 ) ? theFirstNode1 : theFirstNode2;
+ const SMDS_MeshNode* n2 = ( iSide == 0 ) ? theSecondNode1 : theSecondNode2;
+ int firstIndex = -1, secondIndex = -1;
+ for (eIt = elemSet->begin(); eIt != elemSet->end(); eIt++ ) {
+ const SMDS_MeshElement* elem = (*eIt).second;
+ if ( firstIndex < 0 ) firstIndex = elem->GetNodeIndex( n1 );
+ if ( secondIndex < 0 ) secondIndex = elem->GetNodeIndex( n2 );
+ if ( firstIndex > -1 && secondIndex > -1 ) break;
+ }
+ if ( firstIndex < 0 || secondIndex < 0 ) {
+ // we can simply return until temporary faces created
+ return (iSide == 0 ) ? SEW_BAD_SIDE1_NODES : SEW_BAD_SIDE2_NODES;
+ }
+
+ // -----------------------------------------------------------
+ // 1a. Collect nodes of existing faces
+ // and build set of face nodes in order to detect missing
+ // faces corresponing to sides of volumes
+ // -----------------------------------------------------------
set< set <const SMDS_MeshNode*> > setOfFaceNodeSet;
// loop on the given element of a side
for (eIt = elemSet->begin(); eIt != elemSet->end(); eIt++ ) {
- const SMDS_MeshElement* elem = *eIt;
+ //const SMDS_MeshElement* elem = *eIt;
+ const SMDS_MeshElement* elem = (*eIt).second;
if ( elem->GetType() == SMDSAbs_Face ) {
faceSet->insert( elem );
set <const SMDS_MeshNode*> faceNodeSet;
- if(elem->IsQuadratic()) {
- const SMDS_QuadraticFaceOfNodes* F =
- static_cast<const SMDS_QuadraticFaceOfNodes*>(elem);
- // use special nodes iterator
- SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
- while( anIter->more() ) {
- const SMDS_MeshNode* n = anIter->next();
- nodeSet->insert( n );
- faceNodeSet.insert( n );
- }
- }
- else {
- SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
- while ( nodeIt->more() ) {
- const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
- nodeSet->insert( n );
- faceNodeSet.insert( n );
- }
+ SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
+ while ( nodeIt->more() ) {
+ const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+ nodeSet->insert( n );
+ faceNodeSet.insert( n );
}
setOfFaceNodeSet.insert( faceNodeSet );
}
aFreeFace = aMesh->FindFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] );
}
else {
- vector<const SMDS_MeshNode *> poly_nodes (nbNodes);
- for (int inode = 0; inode < nbNodes; inode++) {
- poly_nodes[inode] = fNodes[inode];
- }
+ vector<const SMDS_MeshNode *> poly_nodes ( fNodes, & fNodes[nbNodes]);
aFreeFace = aMesh->FindFace(poly_nodes);
}
}
aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] );
}
else {
- vector<const SMDS_MeshNode *> poly_nodes (nbNodes);
- for (int inode = 0; inode < nbNodes; inode++) {
- poly_nodes[inode] = fNodes[inode];
- }
+ vector<const SMDS_MeshNode *> poly_nodes ( fNodes, & fNodes[nbNodes]);
aFreeFace = aTmpFacesMesh.AddPolygonalFace(poly_nodes);
}
}
const SMDS_MeshElement* e = invElemIt->next();
if ( faceSet->find( e ) != faceSet->end() )
nbSharedNodes++;
- if ( elemSet->find( e ) != elemSet->end() )
+ if ( elemSet->find( e->GetID() ) != elemSet->end() )
nbSharedNodes++;
}
}
// choose a face most close to the bary center of the opposite side
gp_XYZ aBC( 0., 0., 0. );
set <const SMDS_MeshNode*> addedNodes;
- set<const SMDS_MeshElement*> * elemSet2 = elemSetPtr[ 1 - iSide ];
+ map<int,const SMDS_MeshElement*> * elemSet2 = elemSetPtr[ 1 - iSide ];
eIt = elemSet2->begin();
for ( eIt = elemSet2->begin(); eIt != elemSet2->end(); eIt++ ) {
- SMDS_ElemIteratorPtr nodeIt = (*eIt)->nodesIterator();
+ SMDS_ElemIteratorPtr nodeIt = (*eIt).second->nodesIterator();
while ( nodeIt->more() ) { // loop on free face nodes
const SMDS_MeshNode* n =
static_cast<const SMDS_MeshNode*>( nodeIt->next() );
const SMDS_MeshElement* e = invElemIt->next();
// get a new suite of nodes: make replacement
int nbReplaced = 0, i = 0, nbNodes = e->NbNodes();
- const SMDS_MeshNode* nodes[ 8 ];
+ vector< const SMDS_MeshNode*> nodes( nbNodes );
SMDS_ElemIteratorPtr nIt = e->nodesIterator();
while ( nIt->more() ) {
const SMDS_MeshNode* n =
// elemIDsToRemove.push_back( e->GetID() );
// else
if ( nbReplaced )
- aMesh->ChangeElementNodes( e, nodes, nbNodes );
+ aMesh->ChangeElementNodes( e, & nodes[0], nbNodes );
}
}