#include "SMDS_FacePosition.hxx"
#include "SMDS_SpacePosition.hxx"
#include "SMDS_QuadraticFaceOfNodes.hxx"
+#include "SMDS_MeshGroup.hxx"
#include "SMESHDS_Group.hxx"
#include "SMESHDS_Mesh.hxx"
#include "SMESH_ControlsDef.hxx"
#include "SMESH_MesherHelper.hxx"
#include "SMESH_OctreeNode.hxx"
+#include "SMESH_Group.hxx"
#include "utilities.h"
-#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TopTools_ListOfShape.hxx>
-#include <math.h>
-#include <gp_Dir.hxx>
-#include <gp_Vec.hxx>
-#include <gp_Ax1.hxx>
-#include <gp_Trsf.hxx>
-#include <gp_Lin.hxx>
-#include <gp_XYZ.hxx>
-#include <gp_XY.hxx>
-#include <gp.hxx>
-#include <gp_Pln.hxx>
#include <BRep_Tool.hxx>
-#include <Geom_Curve.hxx>
-#include <Geom_Surface.hxx>
-#include <Geom2d_Curve.hxx>
+#include <ElCLib.hxx>
#include <Extrema_GenExtPS.hxx>
#include <Extrema_POnSurf.hxx>
+#include <Geom2d_Curve.hxx>
#include <GeomAdaptor_Surface.hxx>
-#include <ElCLib.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_Surface.hxx>
#include <TColStd_ListOfInteger.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
+#include <gp.hxx>
+#include <gp_Ax1.hxx>
+#include <gp_Dir.hxx>
+#include <gp_Lin.hxx>
+#include <gp_Pln.hxx>
+#include <gp_Trsf.hxx>
+#include <gp_Vec.hxx>
+#include <gp_XY.hxx>
+#include <gp_XYZ.hxx>
+#include <math.h>
#include <map>
#include <set>
typedef map<const SMDS_MeshElement*, list<const SMDS_MeshNode*> > TElemOfNodeListMap;
typedef map<const SMDS_MeshElement*, list<const SMDS_MeshElement*> > TElemOfElemListMap;
-typedef map<const SMDS_MeshNode*, list<const SMDS_MeshNode*> > TNodeOfNodeListMap;
-typedef TNodeOfNodeListMap::iterator TNodeOfNodeListMapItr;
//typedef map<const SMDS_MeshNode*, vector<const SMDS_MeshNode*> > TNodeOfNodeVecMap;
//typedef TNodeOfNodeVecMap::iterator TNodeOfNodeVecMapItr;
-typedef map<const SMDS_MeshElement*, vector<TNodeOfNodeListMapItr> > TElemOfVecOfNnlmiMap;
//typedef map<const SMDS_MeshElement*, vector<TNodeOfNodeVecMapItr> > TElemOfVecOfMapNodesMap;
struct TNodeXYZ : public gp_XYZ {
TNodeXYZ( const SMDS_MeshNode* n ):gp_XYZ( n->X(), n->Y(), n->Z() ) {}
};
-typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink;
-
-/*!
- * \brief A sorted pair of nodes
- */
-struct TLink: public NLink
-{
- TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 )
- { if ( n1->GetID() < n2->GetID() ) std::swap( first, second ); }
- TLink(const NLink& link ):NLink( link )
- { if ( first->GetID() < second->GetID() ) std::swap( first, second ); }
-};
-
//=======================================================================
//function : SMESH_MeshEditor
//purpose :
//=======================================================================
-SMESH_MeshEditor::SMESH_MeshEditor( SMESH_Mesh* theMesh ):
-myMesh( theMesh )
+SMESH_MeshEditor::SMESH_MeshEditor( SMESH_Mesh* theMesh )
+ :myMesh( theMesh ) // theMesh may be NULL
{
}
if ( !elem )
continue;
- // Find sub-meshes to notify about modification
- SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
- while ( nodeIt->more() ) {
- const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
- const SMDS_PositionPtr& aPosition = node->GetPosition();
- if ( aPosition.get() ) {
- if ( int aShapeID = aPosition->GetShapeId() ) {
+ // Notify VERTEX sub-meshes about modification
+ if ( isNodes ) {
+ const SMDS_MeshNode* node = cast2Node( elem );
+ if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX )
+ if ( int aShapeID = node->GetPosition()->GetShapeId() )
if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( aShapeID ) )
smmap.insert( sm );
- }
- }
}
+ // Find sub-meshes to notify about modification
+// SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
+// while ( nodeIt->more() ) {
+// const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+// const SMDS_PositionPtr& aPosition = node->GetPosition();
+// if ( aPosition.get() ) {
+// if ( int aShapeID = aPosition->GetShapeId() ) {
+// if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( aShapeID ) )
+// smmap.insert( sm );
+// }
+// }
+// }
// Do remove
if ( isNodes )
(*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 );
+// // Check if the whole mesh becomes empty
+// if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( 1 ) )
+// sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
return true;
}
set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
for ( ; grIt != groups.end(); grIt++ ) {
SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *grIt );
- if ( group && group->SMDSGroup().Contains( elemInGroups ))
+ if ( group && group->Contains( elemInGroups ))
group->SMDSGroup().Add( elemToAdd );
}
}
// 1. map of elements with their linkIDs
// 2. map of linkIDs with their elements
- map< TLink, list< const SMDS_MeshElement* > > mapLi_listEl;
- map< TLink, list< const SMDS_MeshElement* > >::iterator itLE;
- map< const SMDS_MeshElement*, set< TLink > > mapEl_setLi;
- map< const SMDS_MeshElement*, set< TLink > >::iterator itEL;
+ map< SMESH_TLink, list< const SMDS_MeshElement* > > mapLi_listEl;
+ map< SMESH_TLink, list< const SMDS_MeshElement* > >::iterator itLE;
+ map< const SMDS_MeshElement*, set< SMESH_TLink > > mapEl_setLi;
+ map< const SMDS_MeshElement*, set< SMESH_TLink > >::iterator itEL;
TIDSortedElemSet::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
// fill maps
for ( i = 0; i < 3; i++ ) {
- TLink link( aNodes[i], aNodes[i+1] );
+ SMESH_TLink link( aNodes[i], aNodes[i+1] );
// check if elements sharing a link can be fused
itLE = mapLi_listEl.find( link );
if ( itLE != mapLi_listEl.end() ) {
int nbElems = (*itLE).second.size();
if ( nbElems < 2 ) {
const SMDS_MeshElement* elem = (*itLE).second.front();
- TLink link = (*itLE).first;
+ SMESH_TLink link = (*itLE).first;
mapEl_setLi[ elem ].erase( link );
if ( mapEl_setLi[ elem ].empty() )
mapEl_setLi.erase( elem );
// search elements to fuse starting from startElem or links of elements
// fused earlyer - startLinks
- list< TLink > startLinks;
+ list< SMESH_TLink > startLinks;
while ( startElem || !startLinks.empty() ) {
while ( !startElem && !startLinks.empty() ) {
// Get an element to start, by a link
- TLink linkId = startLinks.front();
+ SMESH_TLink linkId = startLinks.front();
startLinks.pop_front();
itLE = mapLi_listEl.find( linkId );
if ( itLE != mapLi_listEl.end() ) {
if ( startElem ) {
// Get candidates to be fused
const SMDS_MeshElement *tr1 = startElem, *tr2 = 0, *tr3 = 0;
- const TLink *link12, *link13;
+ const SMESH_TLink *link12, *link13;
startElem = 0;
ASSERT( mapEl_setLi.find( tr1 ) != mapEl_setLi.end() );
- set< TLink >& setLi = mapEl_setLi[ tr1 ];
+ set< SMESH_TLink >& setLi = mapEl_setLi[ tr1 ];
ASSERT( !setLi.empty() );
- set< TLink >::iterator itLi;
+ set< SMESH_TLink >::iterator itLi;
for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ )
{
- const TLink & link = (*itLi);
+ const SMESH_TLink & link = (*itLi);
itLE = mapLi_listEl.find( link );
if ( itLE == mapLi_listEl.end() )
continue;
}
// add other links of elem to list of links to re-start from
- set< TLink >& links = mapEl_setLi[ elem ];
- set< TLink >::iterator it;
+ set< SMESH_TLink >& links = mapEl_setLi[ elem ];
+ set< SMESH_TLink >::iterator it;
for ( it = links.begin(); it != links.end(); it++ ) {
- const TLink& link2 = (*it);
+ const SMESH_TLink& link2 = (*it);
if ( link2 != link )
startLinks.push_back( link2 );
}
// fix nodes on mesh boundary
if ( checkBoundaryNodes ) {
- typedef pair<const SMDS_MeshNode*, const SMDS_MeshNode*> TLink;
- map< TLink, int > linkNbMap; // how many times a link encounters in elemsOnFace
- map< TLink, int >::iterator link_nb;
+ map< NLink, int > linkNbMap; // how many times a link encounters in elemsOnFace
+ map< NLink, int >::iterator link_nb;
// put all elements links to linkNbMap
list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();
for ( ; elemIt != elemsOnFace.end(); ++elemIt ) {
const SMDS_MeshNode* curNode, *prevNode = elem->GetNode( nbn );
for ( int iN = 0; iN < nbn; ++iN ) {
curNode = elem->GetNode( iN );
- TLink link;
+ NLink link;
if ( curNode < prevNode ) link = make_pair( curNode , prevNode );
else link = make_pair( prevNode , curNode );
prevNode = curNode;
}
//=======================================================================
-//function : sweepElement
-//purpose :
+/*!
+ * \brief Create elements by sweeping an element
+ * \param elem - element to sweep
+ * \param newNodesItVec - nodes generated from each node of the element
+ * \param newElems - generated elements
+ * \param nbSteps - number of sweeping steps
+ * \param srcElements - to append elem for each generated element
+ */
//=======================================================================
-static void sweepElement(SMESHDS_Mesh* aMesh,
- const SMDS_MeshElement* elem,
- const vector<TNodeOfNodeListMapItr> & newNodesItVec,
- list<const SMDS_MeshElement*>& newElems,
- const int nbSteps,
- SMESH_SequenceOfElemPtr& myLastCreatedElems)
+void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem,
+ const vector<TNodeOfNodeListMapItr> & newNodesItVec,
+ list<const SMDS_MeshElement*>& newElems,
+ const int nbSteps,
+ SMESH_SequenceOfElemPtr& srcElements)
{
+ SMESHDS_Mesh* aMesh = GetMeshDS();
+
// Loop on elem nodes:
// find new nodes and detect same nodes indices
int nbNodes = elem->NbNodes();
- //---PR
- //list<const SMDS_MeshNode*>::const_iterator itNN[ nbNodes ];
- vector<list<const SMDS_MeshNode*>::const_iterator> itNN( nbNodes );
- itNN.reserve(nbNodes);
- //---PR
- //const SMDS_MeshNode* prevNod[ nbNodes ], *nextNod[ nbNodes ];
+ vector < list< const SMDS_MeshNode* >::const_iterator > itNN( nbNodes );
vector<const SMDS_MeshNode*> prevNod( nbNodes );
vector<const SMDS_MeshNode*> nextNod( nbNodes );
vector<const SMDS_MeshNode*> midlNod( nbNodes );
}
// make new elements
- int iStep;//, nbSteps = newNodesItVec[ 0 ]->second.size();
- for (iStep = 0; iStep < nbSteps; iStep++ ) {
+ for (int iStep = 0; iStep < nbSteps; iStep++ ) {
// get next nodes
for ( iNode = 0; iNode < nbNodes; iNode++ ) {
if(issimple[iNode]) {
if ( aNewElem ) {
newElems.push_back( aNewElem );
myLastCreatedElems.Append(aNewElem);
+ srcElements.Append( elem );
}
// set new prev nodes
}
//=======================================================================
-//function : makeWalls
-//purpose : create 1D and 2D elements around swept elements
+/*!
+ * \brief Create 1D and 2D elements around swept elements
+ * \param mapNewNodes - source nodes and ones generated from them
+ * \param newElemsMap - source elements and ones generated from them
+ * \param elemNewNodesMap - nodes generated from each node of each element
+ * \param elemSet - all swept elements
+ * \param nbSteps - number of sweeping steps
+ * \param srcElements - to append elem for each generated element
+ */
//=======================================================================
-static void makeWalls (SMESHDS_Mesh* aMesh,
- TNodeOfNodeListMap & mapNewNodes,
- TElemOfElemListMap & newElemsMap,
- TElemOfVecOfNnlmiMap & elemNewNodesMap,
- TIDSortedElemSet& elemSet,
- const int nbSteps,
- SMESH_SequenceOfElemPtr& myLastCreatedElems)
+void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes,
+ TElemOfElemListMap & newElemsMap,
+ TElemOfVecOfNnlmiMap & elemNewNodesMap,
+ TIDSortedElemSet& elemSet,
+ const int nbSteps,
+ SMESH_SequenceOfElemPtr& srcElements)
{
ASSERT( newElemsMap.size() == elemNewNodesMap.size() );
+ SMESHDS_Mesh* aMesh = GetMeshDS();
// Find nodes belonging to only one initial element - sweep them to get edges.
if(!NotCreateEdge) {
vector<TNodeOfNodeListMapItr> newNodesItVec( 1, nList );
list<const SMDS_MeshElement*> newEdges;
- sweepElement( aMesh, node, newNodesItVec, newEdges, nbSteps, myLastCreatedElems );
+ sweepElement( node, newNodesItVec, newEdges, nbSteps, srcElements );
}
}
}
// create a ceiling edge
if (!elem->IsQuadratic()) {
if ( !aMesh->FindEdge( vecNewNodes[ 0 ]->second.back(),
- vecNewNodes[ 1 ]->second.back()))
+ vecNewNodes[ 1 ]->second.back())) {
myLastCreatedElems.Append(aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
vecNewNodes[ 1 ]->second.back()));
+ srcElements.Append( myLastCreatedElems.Last() );
+ }
}
else {
if ( !aMesh->FindEdge( vecNewNodes[ 0 ]->second.back(),
vecNewNodes[ 1 ]->second.back(),
- vecNewNodes[ 2 ]->second.back()))
+ vecNewNodes[ 2 ]->second.back())) {
myLastCreatedElems.Append(aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
vecNewNodes[ 1 ]->second.back(),
vecNewNodes[ 2 ]->second.back()));
+ srcElements.Append( myLastCreatedElems.Last() );
+ }
}
}
if ( elem->GetType() != SMDSAbs_Face )
hasFreeLinks = true;
// make an edge and a ceiling for a new edge
if ( !aMesh->FindEdge( n1, n2 )) {
- myLastCreatedElems.Append(aMesh->AddEdge( n1, n2 ));
+ myLastCreatedElems.Append(aMesh->AddEdge( n1, n2 )); // free link edge
+ srcElements.Append( myLastCreatedElems.Last() );
}
n1 = vecNewNodes[ iNode ]->second.back();
n2 = vecNewNodes[ iNext ]->second.back();
if ( !aMesh->FindEdge( n1, n2 )) {
- myLastCreatedElems.Append(aMesh->AddEdge( n1, n2 ));
+ myLastCreatedElems.Append(aMesh->AddEdge( n1, n2 )); // ceiling edge
+ srcElements.Append( myLastCreatedElems.Last() );
}
}
}
// find medium node
const SMDS_MeshNode* n3 = vecNewNodes[ iNode+nbn ]->first;
if ( !aMesh->FindEdge( n1, n2, n3 )) {
- myLastCreatedElems.Append(aMesh->AddEdge( n1, n2, n3 ));
+ myLastCreatedElems.Append(aMesh->AddEdge( n1, n2, n3 )); // free link edge
+ srcElements.Append( myLastCreatedElems.Last() );
}
n1 = vecNewNodes[ iNode ]->second.back();
n2 = vecNewNodes[ iNext ]->second.back();
n3 = vecNewNodes[ iNode+nbn ]->second.back();
if ( !aMesh->FindEdge( n1, n2, n3 )) {
- myLastCreatedElems.Append(aMesh->AddEdge( n1, n2, n3 ));
+ myLastCreatedElems.Append(aMesh->AddEdge( n1, n2, n3 )); // ceiling edge
+ srcElements.Append( myLastCreatedElems.Last() );
}
}
}
if ( hasFreeLinks ) {
list<const SMDS_MeshElement*> & newVolumes = itElem->second;
- int iStep; //, nbSteps = vecNewNodes[0]->second.size();
int iVol, volNb, nbVolumesByStep = newVolumes.size() / nbSteps;
- set<const SMDS_MeshNode*> initNodeSet, faceNodeSet;
- for ( iNode = 0; iNode < nbNodes; iNode++ )
+ set<const SMDS_MeshNode*> initNodeSet, topNodeSet, faceNodeSet;
+ for ( iNode = 0; iNode < nbNodes; iNode++ ) {
initNodeSet.insert( vecNewNodes[ iNode ]->first );
-
+ topNodeSet .insert( vecNewNodes[ iNode ]->second.back() );
+ }
for ( volNb = 0; volNb < nbVolumesByStep; volNb++ ) {
list<const SMDS_MeshElement*>::iterator v = newVolumes.begin();
iVol = 0;
while ( iVol++ < volNb ) v++;
- // find indices of free faces of a volume
- list< int > fInd;
+ // find indices of free faces of a volume and their source edges
+ list< int > freeInd;
+ list< const SMDS_MeshElement* > srcEdges; // source edges of free faces
SMDS_VolumeTool vTool( *v );
int iF, nbF = vTool.NbFaces();
for ( iF = 0; iF < nbF; iF ++ ) {
if (vTool.IsFreeFace( iF ) &&
vTool.GetFaceNodes( iF, faceNodeSet ) &&
initNodeSet != faceNodeSet) // except an initial face
- fInd.push_back( iF );
+ {
+ if ( nbSteps == 1 && faceNodeSet == topNodeSet )
+ continue;
+ freeInd.push_back( iF );
+ // find source edge of a free face iF
+ vector<const SMDS_MeshNode*> commonNodes; // shared by the initial and free faces
+ commonNodes.resize( initNodeSet.size(), NULL ); // avoid spoiling memory
+ std::set_intersection( faceNodeSet.begin(), faceNodeSet.end(),
+ initNodeSet.begin(), initNodeSet.end(),
+ commonNodes.begin());
+ if ( (*v)->IsQuadratic() )
+ srcEdges.push_back(aMesh->FindEdge (commonNodes[0],commonNodes[1],commonNodes[2]));
+ else
+ srcEdges.push_back(aMesh->FindEdge (commonNodes[0],commonNodes[1]));
+#ifdef _DEBUG_
+ if ( !srcEdges.back() )
+ {
+ cout << "SMESH_MeshEditor::makeWalls(), no source edge found for a free face #"
+ << iF << " of volume #" << vTool.ID() << endl;
+ }
+#endif
+ }
}
- if ( fInd.empty() )
+ if ( freeInd.empty() )
continue;
- // create faces for all steps
- // if such a face has been already created by sweep of edge, assure that its orientation is OK
- for ( iStep = 0; iStep < nbSteps; iStep++ ) {
+ // create faces for all steps;
+ // if such a face has been already created by sweep of edge,
+ // assure that its orientation is OK
+ for ( int iStep = 0; iStep < nbSteps; iStep++ ) {
vTool.Set( *v );
vTool.SetExternalNormal();
- list< int >::iterator ind = fInd.begin();
- for ( ; ind != fInd.end(); ind++ ) {
+ list< int >::iterator ind = freeInd.begin();
+ list< const SMDS_MeshElement* >::iterator srcEdge = srcEdges.begin();
+ for ( ; ind != freeInd.end(); ++ind, ++srcEdge ) // loop on free faces
+ {
const SMDS_MeshNode** nodes = vTool.GetFaceNodes( *ind );
int nbn = vTool.NbFaceNodes( *ind );
switch ( nbn ) {
aMesh->ChangeElementNodes( f, nodes, nbn );
}
}
- }
+ while ( srcElements.Length() < myLastCreatedElems.Length() )
+ srcElements.Append( *srcEdge );
+
+ } // loop on free faces
+
// go to the next volume
iVol = 0;
while ( iVol++ < nbVolumesByStep ) v++;
}
} // sweep free links into faces
- // make a ceiling face with a normal external to a volume
+ // Make a ceiling face with a normal external to a volume
SMDS_VolumeTool lastVol( itElem->second.back() );
myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes));
}
} // switch
+
+ while ( srcElements.Length() < myLastCreatedElems.Length() )
+ srcElements.Append( myLastCreatedElems.Last() );
}
} // loop on swept elements
}
//purpose :
//=======================================================================
-void SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems,
- const gp_Ax1& theAxis,
- const double theAngle,
- const int theNbSteps,
- const double theTol,
- const bool theMakeWalls)
+SMESH_MeshEditor::PGroupIDs
+SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems,
+ const gp_Ax1& theAxis,
+ const double theAngle,
+ const int theNbSteps,
+ const double theTol,
+ const bool theMakeGroups,
+ const bool theMakeWalls)
{
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
+ // source elements for each generated one
+ SMESH_SequenceOfElemPtr srcElems, srcNodes;
+
MESSAGE( "RotationSweep()");
gp_Trsf aTrsf;
aTrsf.SetRotation( theAxis, theAngle );
// loop on elem nodes
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
- while ( itN->more() ) {
-
+ while ( itN->more() )
+ {
// check if a node has been already sweeped
- const SMDS_MeshNode* node =
- static_cast<const SMDS_MeshNode*>( itN->next() );
+ const SMDS_MeshNode* node = cast2Node( itN->next() );
TNodeOfNodeListMapItr nIt = mapNewNodes.find( node );
if ( nIt == mapNewNodes.end() ) {
nIt = mapNewNodes.insert( make_pair( node, list<const SMDS_MeshNode*>() )).first;
//aTrsf.Transforms( coord[0], coord[1], coord[2] );
newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
myLastCreatedNodes.Append(newNode);
+ srcNodes.Append( node );
listNewNodes.push_back( newNode );
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);
+ srcNodes.Append( node );
}
listNewNodes.push_back( newNode );
}
newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
myLastCreatedNodes.Append(newNode);
listNewNodes.push_back( newNode );
+ srcNodes.Append( node );
aTrsf2.Transforms( coord[0], coord[1], coord[2] );
newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
myLastCreatedNodes.Append(newNode);
+ srcNodes.Append( node );
listNewNodes.push_back( newNode );
}
}
newNodesItVec.push_back( nIt );
}
// make new elements
- sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], theNbSteps, myLastCreatedElems );
+ sweepElement( elem, newNodesItVec, newElemsMap[elem], theNbSteps, srcElems );
}
if ( theMakeWalls )
- makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes,
- theElems, theNbSteps, myLastCreatedElems );
+ makeWalls( mapNewNodes, newElemsMap, mapElemNewNodes, theElems, theNbSteps, srcElems );
+
+ PGroupIDs newGroupIDs;
+ if ( theMakeGroups )
+ newGroupIDs = generateGroups( srcNodes, srcElems, "rotated");
+
+ return newGroupIDs;
}
//purpose :
//=======================================================================
-void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
- const gp_Vec& theStep,
- const int theNbSteps,
- TElemOfElemListMap& newElemsMap,
- const int theFlags,
- const double theTolerance)
+SMESH_MeshEditor::PGroupIDs
+SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
+ const gp_Vec& theStep,
+ const int theNbSteps,
+ TElemOfElemListMap& newElemsMap,
+ const bool theMakeGroups,
+ const int theFlags,
+ const double theTolerance)
{
ExtrusParam aParams;
aParams.myDir = gp_Dir(theStep);
for(i=1; i<=theNbSteps; i++)
aParams.mySteps->Append(theStep.Magnitude());
- ExtrusionSweep(theElems,aParams,newElemsMap,theFlags,theTolerance);
-
+ return
+ ExtrusionSweep(theElems,aParams,newElemsMap,theMakeGroups,theFlags,theTolerance);
}
//purpose :
//=======================================================================
-void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
- ExtrusParam& theParams,
- TElemOfElemListMap& newElemsMap,
- const int theFlags,
- const double theTolerance)
+SMESH_MeshEditor::PGroupIDs
+SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
+ ExtrusParam& theParams,
+ TElemOfElemListMap& newElemsMap,
+ const bool theMakeGroups,
+ const int theFlags,
+ const double theTolerance)
{
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
+ // source elements for each generated one
+ SMESH_SequenceOfElemPtr srcElems, srcNodes;
+
SMESHDS_Mesh* aMesh = GetMeshDS();
int nbsteps = theParams.mySteps->Length();
// loop on elem nodes
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
- while ( itN->more() ) {
-
+ while ( itN->more() )
+ {
// check if a node has been already sweeped
- const SMDS_MeshNode* node =
- static_cast<const SMDS_MeshNode*>( itN->next() );
+ const SMDS_MeshNode* node = cast2Node( itN->next() );
TNodeOfNodeListMap::iterator nIt = mapNewNodes.find( node );
//TNodeOfNodeVecMap::iterator nIt = mapNewNodes.find( node );
if ( nIt == mapNewNodes.end() ) {
else {
const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z);
myLastCreatedNodes.Append(newNode);
+ srcNodes.Append( node );
listNewNodes.push_back( newNode );
}
}
else {
const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
myLastCreatedNodes.Append(newNode);
+ srcNodes.Append( node );
listNewNodes.push_back( newNode );
//vecNewNodes[i]=newNode;
}
else {
const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z);
myLastCreatedNodes.Append(newNode);
+ srcNodes.Append( node );
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);
+ srcNodes.Append( node );
listNewNodes.push_back( newNode );
}
}
newNodesItVec.push_back( nIt );
}
// make new elements
- sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], nbsteps, myLastCreatedElems );
+ sweepElement( elem, newNodesItVec, newElemsMap[elem], nbsteps, srcElems );
}
if( theFlags & EXTRUSION_FLAG_BOUNDARY ) {
- makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, nbsteps, myLastCreatedElems );
+ makeWalls( mapNewNodes, newElemsMap, mapElemNewNodes, theElems, nbsteps, srcElems );
}
+ PGroupIDs newGroupIDs;
+ if ( theMakeGroups )
+ newGroupIDs = generateGroups( srcNodes, srcElems, "extruded");
+
+ return newGroupIDs;
}
const bool theHasAngles,
list<double>& theAngles,
const bool theHasRefPoint,
- const gp_Pnt& theRefPoint)
+ const gp_Pnt& theRefPoint,
+ const bool theMakeGroups)
{
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
- MESSAGE("SMESH_MeshEditor::ExtrusionAlongTrack")
+ // source elements for each generated one
+ SMESH_SequenceOfElemPtr srcElems, srcNodes;
+
int j, aNbTP, aNbE, aNb;
double aT1, aT2, aT, aAngle, aX, aY, aZ;
std::list<double> aPrms;
newNodesItVec.reserve( elem->NbNodes() );
// loop on elem nodes
+ int nodeIndex = -1;
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
- while ( itN->more() ) {
-
+ while ( itN->more() )
+ {
+ ++nodeIndex;
// check if a node has been already processed
const SMDS_MeshNode* node =
static_cast<const SMDS_MeshNode*>( itN->next() );
double z = ( aPN1.Z() + aPN0.Z() )/2.;
const SMDS_MeshNode* newNode = aMesh->AddNode(x,y,z);
myLastCreatedNodes.Append(newNode);
+ srcNodes.Append( node );
listNewNodes.push_back( newNode );
}
aX = aPN1.X();
aZ = aPN1.Z();
const SMDS_MeshNode* newNode = aMesh->AddNode( aX, aY, aZ );
myLastCreatedNodes.Append(newNode);
+ srcNodes.Append( node );
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);
+ srcNodes.Append( node );
myLastCreatedNodes.Append(newN);
aNodes[2*i] = newN;
aNodes[2*i+1] = N;
// make new elements
//sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem],
// newNodesItVec[0]->second.size(), myLastCreatedElems );
- sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem],
- aNbTP-1, myLastCreatedElems );
+ sweepElement( elem, newNodesItVec, newElemsMap[elem], aNbTP-1, srcElems );
}
- makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElements,
- aNbTP-1, myLastCreatedElems );
+ makeWalls( mapNewNodes, newElemsMap, mapElemNewNodes, theElements, aNbTP-1, srcElems );
+
+ if ( theMakeGroups )
+ generateGroups( srcNodes, srcElems, "extruded");
return EXTR_OK;
}
//purpose :
//=======================================================================
-void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
- const gp_Trsf& theTrsf,
- const bool theCopy)
+SMESH_MeshEditor::PGroupIDs
+SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
+ const gp_Trsf& theTrsf,
+ const bool theCopy,
+ const bool theMakeGroups,
+ SMESH_Mesh* theTargetMesh)
{
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
- bool needReverse;
+ bool needReverse = false;
+ string groupPostfix;
switch ( theTrsf.Form() ) {
case gp_PntMirror:
+ case gp_Ax1Mirror:
case gp_Ax2Mirror:
needReverse = true;
+ groupPostfix = "mirrored";
+ break;
+ case gp_Rotation:
+ groupPostfix = "rotated";
+ break;
+ case gp_Translation:
+ groupPostfix = "translated";
+ break;
+ case gp_Scale:
+ groupPostfix = "scaled";
break;
default:
needReverse = false;
+ groupPostfix = "transformed";
}
- SMESHDS_Mesh* aMesh = GetMeshDS();
+ SMESH_MeshEditor targetMeshEditor( theTargetMesh );
+ SMESHDS_Mesh* aTgtMesh = theTargetMesh ? theTargetMesh->GetMeshDS() : 0;
+ SMESHDS_Mesh* aMesh = GetMeshDS();
+
// map old node to new one
TNodeNodeMap nodeMap;
// nodes mirrored but are not in theElems are to be reversed
TIDSortedElemSet inverseElemSet;
+ // source elements for each generated one
+ SMESH_SequenceOfElemPtr srcElems, srcNodes;
+
// loop on theElems
TIDSortedElemSet::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
while ( itN->more() ) {
// check if a node has been already transformed
- const SMDS_MeshNode* node =
- static_cast<const SMDS_MeshNode*>( itN->next() );
- if (nodeMap.find( node ) != nodeMap.end() )
+ const SMDS_MeshNode* node = cast2Node( itN->next() );
+ pair<TNodeNodeMap::iterator,bool> n2n_isnew =
+ nodeMap.insert( make_pair ( node, node ));
+ if ( !n2n_isnew.second )
continue;
double coord[3];
coord[1] = node->Y();
coord[2] = node->Z();
theTrsf.Transforms( coord[0], coord[1], coord[2] );
- const SMDS_MeshNode * newNode = node;
- if ( theCopy ) {
- newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+ if ( theTargetMesh ) {
+ const SMDS_MeshNode * newNode = aTgtMesh->AddNode( coord[0], coord[1], coord[2] );
+ n2n_isnew.first->second = newNode;
+ myLastCreatedNodes.Append(newNode);
+ srcNodes.Append( node );
+ }
+ else if ( theCopy ) {
+ const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+ n2n_isnew.first->second = newNode;
myLastCreatedNodes.Append(newNode);
+ srcNodes.Append( node );
}
else {
aMesh->MoveNode( node, coord[0], coord[1], coord[2] );
const_cast< SMDS_MeshNode* > ( node )->SetPosition
( SMDS_SpacePosition::originSpacePosition() );
}
- nodeMap.insert( TNodeNodeMap::value_type( node, newNode ));
// keep inverse elements
- if ( !theCopy && needReverse ) {
+ if ( !theCopy && !theTargetMesh && needReverse ) {
SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
while ( invElemIt->more() ) {
const SMDS_MeshElement* iel = invElemIt->next();
}
}
- // either new elements are to be created
- // or a mirrored element are to be reversed
- if ( !theCopy && !needReverse)
- return;
+ // either create new elements or reverse mirrored ones
+ if ( !theCopy && !needReverse && !theTargetMesh )
+ return PGroupIDs();
- if ( !inverseElemSet.empty()) {
- TIDSortedElemSet::iterator invElemIt = inverseElemSet.begin();
- for ( ; invElemIt != inverseElemSet.end(); invElemIt++ )
- theElems.insert( *invElemIt );
- }
+ TIDSortedElemSet::iterator invElemIt = inverseElemSet.begin();
+ for ( ; invElemIt != inverseElemSet.end(); invElemIt++ )
+ theElems.insert( *invElemIt );
// replicate or reverse elements
{ 0, 1, 2, 3, 4, 5, 6, 7 } // FORWARD
};
- for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
+ for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
+ {
const SMDS_MeshElement* elem = *itElem;
if ( !elem || elem->GetType() == SMDSAbs_Node )
continue;
if ( iNode != nbNodes )
continue; // not all nodes transformed
- if ( theCopy ) {
+ if ( theTargetMesh ) {
+ myLastCreatedElems.Append(aTgtMesh->AddPolygonalFace(poly_nodes));
+ srcElems.Append( elem );
+ }
+ else if ( theCopy ) {
myLastCreatedElems.Append(aMesh->AddPolygonalFace(poly_nodes));
+ srcElems.Append( elem );
}
else {
aMesh->ChangePolygonNodes(elem, poly_nodes);
{
// ATTENTION: Reversing is not yet done!!!
const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
- (const SMDS_PolyhedralVolumeOfNodes*) elem;
+ dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>( elem );
if (!aPolyedre) {
MESSAGE("Warning: bad volumic element");
continue;
if ( !allTransformed )
continue; // not all nodes transformed
- if ( theCopy ) {
+ if ( theTargetMesh ) {
+ myLastCreatedElems.Append(aTgtMesh->AddPolyhedralVolume(poly_nodes, quantities));
+ srcElems.Append( elem );
+ }
+ else if ( theCopy ) {
myLastCreatedElems.Append(aMesh->AddPolyhedralVolume(poly_nodes, quantities));
+ srcElems.Append( elem );
}
else {
aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
}
}
break;
- default:;
- }
- continue;
+ default:;
}
+ continue;
+ }
- // Regular elements
- int* i = index[ FORWARD ];
- if ( needReverse && nbNodes > 2) // reverse mirrored faces and volumes
- if ( elemType == SMDSAbs_Face )
- i = index[ REV_FACE ];
- else
- i = index[ nbNodes - 4 ];
+ // Regular elements
+ int* i = index[ FORWARD ];
+ if ( needReverse && nbNodes > 2) // reverse mirrored faces and volumes
+ if ( elemType == SMDSAbs_Face )
+ i = index[ REV_FACE ];
+ else
+ i = index[ nbNodes - 4 ];
if(elem->IsQuadratic()) {
static int anIds[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
if ( iNode != nbNodes )
continue; // not all nodes transformed
- if ( theCopy ) {
- if ( SMDS_MeshElement* copy = AddElement( nodes, elem->GetType(), elem->IsPoly() ))
+ if ( theTargetMesh ) {
+ if ( SMDS_MeshElement* copy =
+ targetMeshEditor.AddElement( nodes, elem->GetType(), elem->IsPoly() )) {
myLastCreatedElems.Append( copy );
+ srcElems.Append( elem );
+ }
}
- else
- {
+ else if ( theCopy ) {
+ if ( SMDS_MeshElement* copy = AddElement( nodes, elem->GetType(), elem->IsPoly() )) {
+ myLastCreatedElems.Append( copy );
+ srcElems.Append( elem );
+ }
+ }
+ else {
// reverse element as it was reversed by transformation
if ( nbNodes > 2 )
aMesh->ChangeElementNodes( elem, &nodes[0], nbNodes );
}
}
+
+ PGroupIDs newGroupIDs;
+
+ if ( theMakeGroups && theCopy ||
+ theMakeGroups && theTargetMesh )
+ newGroupIDs = generateGroups( srcNodes, srcElems, groupPostfix, theTargetMesh );
+
+ return newGroupIDs;
+}
+
+//=======================================================================
+/*!
+ * \brief Create groups of elements made during transformation
+ * \param nodeGens - nodes making corresponding myLastCreatedNodes
+ * \param elemGens - elements making corresponding myLastCreatedElems
+ * \param postfix - to append to names of new groups
+ */
+//=======================================================================
+
+SMESH_MeshEditor::PGroupIDs
+SMESH_MeshEditor::generateGroups(const SMESH_SequenceOfElemPtr& nodeGens,
+ const SMESH_SequenceOfElemPtr& elemGens,
+ const std::string& postfix,
+ SMESH_Mesh* targetMesh)
+{
+ PGroupIDs newGroupIDs( new list<int> );
+ SMESH_Mesh* mesh = targetMesh ? targetMesh : GetMesh();
+
+ // Sort existing groups by types and collect their names
+
+ // to store an old group and a generated new one
+ typedef pair< SMESHDS_GroupBase*, SMDS_MeshGroup* > TOldNewGroup;
+ vector< list< TOldNewGroup > > groupsByType( SMDSAbs_NbElementTypes );
+ // group names
+ set< string > groupNames;
+ //
+ SMDS_MeshGroup* nullNewGroup = (SMDS_MeshGroup*) 0;
+ SMESH_Mesh::GroupIteratorPtr groupIt = GetMesh()->GetGroups();
+ while ( groupIt->more() ) {
+ SMESH_Group * group = groupIt->next();
+ if ( !group ) continue;
+ SMESHDS_GroupBase* groupDS = group->GetGroupDS();
+ if ( !groupDS || groupDS->IsEmpty() ) continue;
+ groupNames.insert( group->GetName() );
+ groupDS->SetStoreName( group->GetName() );
+ groupsByType[ groupDS->GetType() ].push_back( make_pair( groupDS, nullNewGroup ));
+ }
+
+ // Groups creation
+
+ // loop on nodes and elements
+ for ( int isNodes = 0; isNodes < 2; ++isNodes )
+ {
+ const SMESH_SequenceOfElemPtr& gens = isNodes ? nodeGens : elemGens;
+ const SMESH_SequenceOfElemPtr& elems = isNodes ? myLastCreatedNodes : myLastCreatedElems;
+ if ( gens.Length() != elems.Length() )
+ throw SALOME_Exception(LOCALIZED("invalid args"));
+
+ // loop on created elements
+ for (int iElem = 1; iElem <= elems.Length(); ++iElem )
+ {
+ const SMDS_MeshElement* sourceElem = gens( iElem );
+ if ( !sourceElem ) {
+ MESSAGE("generateGroups(): NULL source element");
+ continue;
+ }
+ list< TOldNewGroup > & groupsOldNew = groupsByType[ sourceElem->GetType() ];
+ if ( groupsOldNew.empty() ) {
+ while ( iElem < gens.Length() && gens( iElem+1 ) == sourceElem )
+ ++iElem; // skip all elements made by sourceElem
+ continue;
+ }
+ // collect all elements made by sourceElem
+ list< const SMDS_MeshElement* > resultElems;
+ if ( const SMDS_MeshElement* resElem = elems( iElem ))
+ if ( resElem != sourceElem )
+ resultElems.push_back( resElem );
+ while ( iElem < gens.Length() && gens( iElem+1 ) == sourceElem )
+ if ( const SMDS_MeshElement* resElem = elems( ++iElem ))
+ if ( resElem != sourceElem )
+ resultElems.push_back( resElem );
+ // do not generate element groups from node ones
+ if ( sourceElem->GetType() == SMDSAbs_Node &&
+ elems( iElem )->GetType() != SMDSAbs_Node )
+ continue;
+
+ // add resultElems to groups made by ones the sourceElem belongs to
+ list< TOldNewGroup >::iterator gOldNew, gLast = groupsOldNew.end();
+ for ( gOldNew = groupsOldNew.begin(); gOldNew != gLast; ++gOldNew )
+ {
+ SMESHDS_GroupBase* oldGroup = gOldNew->first;
+ if ( oldGroup->Contains( sourceElem )) // sourceElem in oldGroup
+ {
+ SMDS_MeshGroup* & newGroup = gOldNew->second;
+ if ( !newGroup )// create a new group
+ {
+ // make a name
+ string name = oldGroup->GetStoreName();
+ if ( !targetMesh ) {
+ name += "_";
+ name += postfix;
+ int nb = 0;
+ while ( !groupNames.insert( name ).second ) // name exists
+ {
+ if ( nb == 0 ) {
+ name += "_1";
+ }
+ else {
+ TCollection_AsciiString nbStr(nb+1);
+ name.resize( name.rfind('_')+1 );
+ name += nbStr.ToCString();
+ }
+ ++nb;
+ }
+ }
+ // make a group
+ int id;
+ SMESH_Group* group = mesh->AddGroup( resultElems.back()->GetType(),
+ name.c_str(), id );
+ SMESHDS_Group* groupDS = static_cast<SMESHDS_Group*>(group->GetGroupDS());
+ newGroup = & groupDS->SMDSGroup();
+ newGroupIDs->push_back( id );
+ }
+
+ // fill in a new group
+ list< const SMDS_MeshElement* >::iterator resLast = resultElems.end(), resElemIt;
+ for ( resElemIt = resultElems.begin(); resElemIt != resLast; ++resElemIt )
+ newGroup->Add( *resElemIt );
+ }
+ }
+ } // loop on created elements
+ }// loop on nodes and elements
+
+ return newGroupIDs;
}
//=======================================================================
int aShapeId = FindShape( elem );
set<const SMDS_MeshNode*> nodeSet;
- //const SMDS_MeshNode* curNodes[ nbNodes ], *uniqueNodes[ nbNodes ];
- const SMDS_MeshNode** curNodes = new const SMDS_MeshNode*[ nbNodes ];
- const SMDS_MeshNode** uniqueNodes = new const SMDS_MeshNode*[ nbNodes ];
-
+ vector< const SMDS_MeshNode*> curNodes( nbNodes ), uniqueNodes( nbNodes );
int iUnique = 0, iCur = 0, nbRepl = 0;
vector<int> iRepl( nbNodes );
}
else {
// Change regular element or polygon
- aMesh->ChangeElementNodes( elem, uniqueNodes, nbUniqueNodes );
+ aMesh->ChangeElementNodes( elem, & uniqueNodes[0], nbUniqueNodes );
}
}
else {
rmElemIds.push_back( elem->GetID() );
}
- delete curNodes;
- delete uniqueNodes;
} // loop on elements
// Remove equal nodes and bad elements
Remove( rmNodeIds, true );
Remove( rmElemIds, false );
+
}
const SMDS_MeshElement* elem = invElemIt->next();
// prepare data for a loop on links coming to prevSideNode, of a face or a volume
int iPrevNode, iNode = 0, nbNodes = elem->NbNodes();
- //const SMDS_MeshNode* faceNodes[ nbNodes ];
- const SMDS_MeshNode** faceNodes = new const SMDS_MeshNode*[ nbNodes ];
+ vector< const SMDS_MeshNode* > faceNodes( nbNodes, (const SMDS_MeshNode*)0 );
bool isVolume = volume.Set( elem );
- const SMDS_MeshNode** nodes = isVolume ? volume.GetNodes() : faceNodes;
+ const SMDS_MeshNode** nodes = isVolume ? volume.GetNodes() : & faceNodes[0];
if ( isVolume ) // --volume
hasVolumes = true;
- //else if ( nbNodes > 2 ) { // --face
else if ( elem->GetType()==SMDSAbs_Face ) { // --face
// retrieve all face nodes and find iPrevNode - an index of the prevSideNode
if(elem->IsQuadratic()) {
else {
SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
while ( nIt->more() ) {
- nodes[ iNode ] = static_cast<const SMDS_MeshNode*>( nIt->next() );
+ nodes[ iNode ] = cast2Node( nIt->next() );
if ( nodes[ iNode++ ] == prevSideNode )
iPrevNode = iNode - 1;
}
}
}
}
- delete faceNodes;
} // loop on inverse elements of prevSideNode
if ( !sideNode ) {
{
nodeGroupsToMerge.push_back( list<const SMDS_MeshNode*>() );
nodeGroupsToMerge.back().push_back( *nIt[1] ); // to keep
- nodeGroupsToMerge.back().push_back( *nIt[0] ); // tp remove
+ nodeGroupsToMerge.back().push_back( *nIt[0] ); // to remove
}
}
else {
*/
//=======================================================================
-int SMESH_MeshEditor::ConvertElemToQuadratic(SMESHDS_SubMesh * theSm,
+int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm,
SMESH_MesherHelper& theHelper,
const bool theForce3d)
{
SMESH_subMesh* sm = smIt->next();
if ( SMESHDS_SubMesh *smDS = sm->GetSubMeshDS() ) {
aHelper.SetSubShape( sm->GetSubShape() );
- nbCheckedElems += ConvertElemToQuadratic(smDS, aHelper, theForce3d);
+ nbCheckedElems += convertElemToQuadratic(smDS, aHelper, theForce3d);
}
}
}
*/
//=======================================================================
-int SMESH_MeshEditor::RemoveQuadElem(SMESHDS_SubMesh * theSm,
+int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh * theSm,
SMDS_ElemIteratorPtr theItr,
const int theShapeID)
{
vector<const SMDS_MeshNode*>::iterator nIt = mediumNodes.begin();
for ( ; nIt != mediumNodes.end(); ++nIt ) {
const SMDS_MeshNode* n = *nIt;
- if ( n->NbInverseNodes() == 0 ) {
+ if ( n->NbInverseElements() == 0 ) {
if ( n->GetPosition()->GetShapeId() != theShapeID )
meshDS->RemoveFreeNode( n, meshDS->MeshElements
( n->GetPosition()->GetShapeId() ));
while ( smIt->more() ) {
SMESH_subMesh* sm = smIt->next();
if ( SMESHDS_SubMesh *smDS = sm->GetSubMeshDS() )
- nbCheckedElems += RemoveQuadElem( smDS, smDS->GetElements(), sm->GetId() );
+ nbCheckedElems += removeQuadElem( smDS, smDS->GetElements(), sm->GetId() );
}
}
}
if ( nbCheckedElems < totalNbElems ) // not all elements in submeshes
{
SMESHDS_SubMesh *aSM = 0;
- RemoveQuadElem( aSM, GetMeshDS()->elementsIterator(), 0 );
+ removeQuadElem( aSM, GetMeshDS()->elementsIterator(), 0 );
}
return true;
*/
//================================================================================
+#ifdef _DEBUG_
//#define DEBUG_MATCHING_NODES
+#endif
SMESH_MeshEditor::Sew_Error
SMESH_MeshEditor::FindMatchingNodes(set<const SMDS_MeshElement*>& theSide1,
if ( theSecondNode1 != theSecondNode2 )
nReplaceMap.insert( make_pair( theSecondNode1, theSecondNode2 ));
- set< TLink > linkSet; // set of nodes where order of nodes is ignored
- linkSet.insert( TLink( theFirstNode1, theSecondNode1 ));
+ set< SMESH_TLink > linkSet; // set of nodes where order of nodes is ignored
+ linkSet.insert( SMESH_TLink( theFirstNode1, theSecondNode1 ));
list< NLink > linkList[2];
linkList[0].push_back( NLink( theFirstNode1, theSecondNode1 ));
return SEW_TOPO_DIFF_SETS_OF_ELEMENTS;
}
#ifdef DEBUG_MATCHING_NODES
- cout << " Link 1: " << link[0].first->GetID() <<" "<< link[0].second->GetID()
- << " F 1: " << face[0];
- cout << "| Link 2: " << link[1].first->GetID() <<" "<< link[1].second->GetID()
- << " F 2: " << face[1] << " | Bind: "<<endl ;
+ MESSAGE ( " Link 1: " << link[0].first->GetID() <<" "<< link[0].second->GetID()
+ << " F 1: " << face[0] << "| Link 2: " << link[1].first->GetID() <<" "
+ << link[1].second->GetID() << " F 2: " << face[1] << " | Bind: " ) ;
#endif
int nbN = nbNodes[0];
{
list<const SMDS_MeshNode*>::iterator n2 = notLinkNodes[1].begin();
for ( int i = 0 ; i < nbN - 2; ++i ) {
#ifdef DEBUG_MATCHING_NODES
- cout << (*n1)->GetID() << " to " << (*n2)->GetID() << endl;
+ MESSAGE ( (*n1)->GetID() << " to " << (*n2)->GetID() );
#endif
nReplaceMap.insert( make_pair( *(n1++), *(n2++) ));
}
for ( int i = 0; i < nbN; i++ )
{
const SMDS_MeshNode* n2 = f0->GetNode( i );
- pair< set< TLink >::iterator, bool > iter_isnew =
- linkSet.insert( TLink( n1, n2 ));
+ pair< set< SMESH_TLink >::iterator, bool > iter_isnew =
+ linkSet.insert( SMESH_TLink( n1, n2 ));
if ( !iter_isnew.second ) { // already in a set: no need to process
linkSet.erase( iter_isnew.first );
}
else // new in set == encountered for the first time: add
{
#ifdef DEBUG_MATCHING_NODES
- cout << "Add link 1: " << n1->GetID() << " " << n2->GetID() << " ";
- cout << " | link 2: " << nReplaceMap[n1]->GetID() << " " << nReplaceMap[n2]->GetID() << " " << endl;
+ MESSAGE ( "Add link 1: " << n1->GetID() << " " << n2->GetID() << " "
+ << " | link 2: " << nReplaceMap[n1]->GetID() << " " << nReplaceMap[n2]->GetID() << " " );
#endif
linkList[0].push_back ( NLink( n1, n2 ));
linkList[1].push_back ( NLink( nReplaceMap[n1], nReplaceMap[n2] ));
return SEW_OK;
}
+
+/*!
+ \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+ \param theNodes - identifiers of nodes to be doubled
+ \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
+ nodes. If list of element identifiers is empty then nodes are doubled but
+ they not assigned to elements
+ \return TRUE if operation has been completed successfully, FALSE otherwise
+*/
+bool SMESH_MeshEditor::DoubleNodes( const std::list< int >& theListOfNodes,
+ const std::list< int >& theListOfModifiedElems )
+{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
+ if ( theListOfNodes.size() == 0 )
+ return false;
+
+ SMESHDS_Mesh* aMeshDS = GetMeshDS();
+ if ( !aMeshDS )
+ return false;
+
+ // iterate through nodes and duplicate them
+
+ std::map< const SMDS_MeshNode*, const SMDS_MeshNode* > anOldNodeToNewNode;
+
+ std::list< int >::const_iterator aNodeIter;
+ for ( aNodeIter = theListOfNodes.begin(); aNodeIter != theListOfNodes.end(); ++aNodeIter )
+ {
+ int aCurr = *aNodeIter;
+ SMDS_MeshNode* aNode = (SMDS_MeshNode*)aMeshDS->FindNode( aCurr );
+ if ( !aNode )
+ continue;
+
+ // duplicate node
+
+ const SMDS_MeshNode* aNewNode = aMeshDS->AddNode( aNode->X(), aNode->Y(), aNode->Z() );
+ if ( aNewNode )
+ {
+ anOldNodeToNewNode[ aNode ] = aNewNode;
+ myLastCreatedNodes.Append( aNewNode );
+ }
+ }
+
+ // Create map of new nodes for modified elements
+
+ std::map< SMDS_MeshElement*, vector<const SMDS_MeshNode*> > anElemToNodes;
+
+ std::list< int >::const_iterator anElemIter;
+ for ( anElemIter = theListOfModifiedElems.begin();
+ anElemIter != theListOfModifiedElems.end(); ++anElemIter )
+ {
+ int aCurr = *anElemIter;
+ SMDS_MeshElement* anElem = (SMDS_MeshElement*)aMeshDS->FindElement( aCurr );
+ if ( !anElem )
+ continue;
+
+ vector<const SMDS_MeshNode*> aNodeArr( anElem->NbNodes() );
+
+ SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
+ int ind = 0;
+ while ( anIter->more() )
+ {
+ SMDS_MeshNode* aCurrNode = (SMDS_MeshNode*)anIter->next();
+ if ( aCurr && anOldNodeToNewNode.find( aCurrNode ) != anOldNodeToNewNode.end() )
+ {
+ const SMDS_MeshNode* aNewNode = anOldNodeToNewNode[ aCurrNode ];
+ aNodeArr[ ind++ ] = aNewNode;
+ }
+ else
+ aNodeArr[ ind++ ] = aCurrNode;
+ }
+ anElemToNodes[ anElem ] = aNodeArr;
+ }
+
+ // Change nodes of elements
+
+ std::map< SMDS_MeshElement*, vector<const SMDS_MeshNode*> >::iterator
+ anElemToNodesIter = anElemToNodes.begin();
+ for ( ; anElemToNodesIter != anElemToNodes.end(); ++anElemToNodesIter )
+ {
+ const SMDS_MeshElement* anElem = anElemToNodesIter->first;
+ vector<const SMDS_MeshNode*> aNodeArr = anElemToNodesIter->second;
+ if ( anElem )
+ aMeshDS->ChangeElementNodes( anElem, &aNodeArr[ 0 ], anElem->NbNodes() );
+ }
+
+ return true;
+}