PAL16842 (Genertion of groups when a mesh is transformed)

+  /*!
+   * \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
+   */
+  PGroupIDs generateGroups(const SMESH_SequenceOfElemPtr& nodeGens,
+                           const SMESH_SequenceOfElemPtr& elemGens,
+                           const std::string&             postfix);
This commit is contained in:
eap 2007-11-12 09:58:54 +00:00
parent 117656acc5
commit 0562181892
2 changed files with 414 additions and 127 deletions

View File

@ -35,6 +35,7 @@
#include "SMDS_FacePosition.hxx"
#include "SMDS_SpacePosition.hxx"
#include "SMDS_QuadraticFaceOfNodes.hxx"
#include "SMDS_MeshGroup.hxx"
#include "SMESHDS_Group.hxx"
#include "SMESHDS_Mesh.hxx"
@ -43,6 +44,7 @@
#include "SMESH_ControlsDef.hxx"
#include "SMESH_MesherHelper.hxx"
#include "SMESH_OctreeNode.hxx"
#include "SMESH_Group.hxx"
#include "utilities.h"
@ -82,11 +84,8 @@ using namespace SMESH::Controls;
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 {
@ -2742,17 +2741,24 @@ static bool isReverse(vector<const SMDS_MeshNode*> prevNodes,
}
//=======================================================================
//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();
@ -2832,8 +2838,7 @@ static void sweepElement(SMESHDS_Mesh* aMesh,
}
// 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]) {
@ -3049,6 +3054,7 @@ static void sweepElement(SMESHDS_Mesh* aMesh,
if ( aNewElem ) {
newElems.push_back( aNewElem );
myLastCreatedElems.Append(aNewElem);
srcElements.Append( elem );
}
// set new prev nodes
@ -3059,19 +3065,26 @@ static void sweepElement(SMESHDS_Mesh* aMesh,
}
//=======================================================================
//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.
@ -3099,7 +3112,7 @@ static void makeWalls (SMESHDS_Mesh* aMesh,
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 );
}
}
}
@ -3117,17 +3130,21 @@ static void makeWalls (SMESHDS_Mesh* aMesh,
// 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 )
@ -3155,12 +3172,14 @@ static void makeWalls (SMESHDS_Mesh* aMesh,
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() );
}
}
}
@ -3179,13 +3198,15 @@ static void makeWalls (SMESHDS_Mesh* aMesh,
// 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() );
}
}
}
@ -3198,7 +3219,6 @@ static void makeWalls (SMESHDS_Mesh* aMesh,
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;
@ -3211,24 +3231,51 @@ static void makeWalls (SMESHDS_Mesh* aMesh,
while ( iVol++ < volNb ) v++;
// find indices of free faces of a volume
list< int > fInd;
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 );
// 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 (!commonNodes[ 1 + int((*v)->IsQuadratic()) ]) {
#ifdef _DEBUG_
throw SALOME_Exception(LOCALIZED("Common nodes not found"));
#else
srcEdges.push_back( NULL );
#endif
}
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() )
throw SALOME_Exception(LOCALIZED("Source edge not found"));
#endif
}
}
if ( fInd.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< const SMDS_MeshElement* >::iterator srcEdge = srcEdges.begin();
for ( ; ind != fInd.end(); ++ind, ++srcEdge ) // loop on free faces
{
const SMDS_MeshNode** nodes = vTool.GetFaceNodes( *ind );
int nbn = vTool.NbFaceNodes( *ind );
switch ( nbn ) {
@ -3278,7 +3325,11 @@ static void makeWalls (SMESHDS_Mesh* aMesh,
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++;
@ -3286,7 +3337,7 @@ static void makeWalls (SMESHDS_Mesh* aMesh,
}
} // 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() );
@ -3330,6 +3381,9 @@ static void makeWalls (SMESHDS_Mesh* aMesh,
myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes));
}
} // switch
while ( srcElements.Length() < myLastCreatedElems.Length() )
srcElements.Append( myLastCreatedElems.Last() );
}
} // loop on swept elements
}
@ -3339,16 +3393,21 @@ static void makeWalls (SMESHDS_Mesh* aMesh,
//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 );
@ -3375,11 +3434,10 @@ void SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems,
// 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;
@ -3399,6 +3457,7 @@ void SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems,
//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] );
@ -3408,6 +3467,7 @@ void SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems,
}
newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
myLastCreatedNodes.Append(newNode);
srcNodes.Append( node );
}
listNewNodes.push_back( newNode );
}
@ -3429,9 +3489,11 @@ void SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems,
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 );
}
}
@ -3440,12 +3502,17 @@ void SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems,
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;
}
@ -3498,12 +3565,14 @@ const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x,
//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);
@ -3513,8 +3582,8 @@ void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
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);
}
@ -3523,15 +3592,20 @@ void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
//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();
@ -3555,11 +3629,10 @@ void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
// 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() ) {
@ -3586,6 +3659,7 @@ void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
else {
const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z);
myLastCreatedNodes.Append(newNode);
srcNodes.Append( node );
listNewNodes.push_back( newNode );
}
}
@ -3602,6 +3676,7 @@ void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
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;
}
@ -3627,6 +3702,7 @@ void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
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);
@ -3640,6 +3716,7 @@ void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
else {
const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
myLastCreatedNodes.Append(newNode);
srcNodes.Append( node );
listNewNodes.push_back( newNode );
}
}
@ -3649,12 +3726,17 @@ void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
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;
}
@ -3713,12 +3795,15 @@ SMESH_MeshEditor::Extrusion_Error
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;
@ -3901,9 +3986,11 @@ SMESH_MeshEditor::Extrusion_Error
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() );
@ -3972,6 +4059,7 @@ SMESH_MeshEditor::Extrusion_Error
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();
@ -3979,6 +4067,7 @@ SMESH_MeshEditor::Extrusion_Error
aZ = aPN1.Z();
const SMDS_MeshNode* newNode = aMesh->AddNode( aX, aY, aZ );
myLastCreatedNodes.Append(newNode);
srcNodes.Append( node );
listNewNodes.push_back( newNode );
aPN0 = aPN1;
@ -4004,6 +4093,7 @@ SMESH_MeshEditor::Extrusion_Error
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;
@ -4022,12 +4112,13 @@ SMESH_MeshEditor::Extrusion_Error
// 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;
}
@ -4037,21 +4128,36 @@ SMESH_MeshEditor::Extrusion_Error
//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)
{
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();
@ -4063,6 +4169,9 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
// 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++ ) {
@ -4075,9 +4184,10 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
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> iter_isnew =
nodeMap.insert( make_pair ( node, node ));
if ( !iter_isnew.second )
continue;
double coord[3];
@ -4085,10 +4195,11 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
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] );
const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
iter_isnew.first->second = newNode;
myLastCreatedNodes.Append(newNode);
srcNodes.Append( node );
}
else {
aMesh->MoveNode( node, coord[0], coord[1], coord[2] );
@ -4096,7 +4207,6 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
const_cast< SMDS_MeshNode* > ( node )->SetPosition
( SMDS_SpacePosition::originSpacePosition() );
}
nodeMap.insert( make_pair( node, newNode ));
// keep inverse elements
if ( !theCopy && needReverse ) {
@ -4109,16 +4219,13 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
}
}
// either new elements are to be created
// or a mirrored element are to be reversed
// either create new elements or reverse mirrored ones
if ( !theCopy && !needReverse)
return;
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
@ -4139,7 +4246,8 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
{ 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;
@ -4174,6 +4282,7 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
if ( theCopy ) {
myLastCreatedElems.Append(aMesh->AddPolygonalFace(poly_nodes));
srcElems.Append( elem );
}
else {
aMesh->ChangePolygonNodes(elem, poly_nodes);
@ -4184,7 +4293,7 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
{
// 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;
@ -4213,6 +4322,7 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
if ( theCopy ) {
myLastCreatedElems.Append(aMesh->AddPolyhedralVolume(poly_nodes, quantities));
srcElems.Append( elem );
}
else {
aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
@ -4283,8 +4393,10 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
continue; // not all nodes transformed
if ( theCopy ) {
if ( SMDS_MeshElement* copy = AddElement( nodes, elem->GetType(), elem->IsPoly() ))
if ( SMDS_MeshElement* copy = AddElement( nodes, elem->GetType(), elem->IsPoly() )) {
myLastCreatedElems.Append( copy );
srcElems.Append( elem );
}
}
else
{
@ -4293,6 +4405,133 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
aMesh->ChangeElementNodes( elem, &nodes[0], nbNodes );
}
}
PGroupIDs newGroupIDs;
if ( theCopy && theMakeGroups )
newGroupIDs = generateGroups( srcNodes, srcElems, groupPostfix );
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)
{
PGroupIDs newGroupIDs( new list<int> );
// Sort existing groups by types and collect their names
// store an old group and a generated new one
typedef pair< SMESHDS_Group*, 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_Group* groupDS = dynamic_cast< SMESHDS_Group* >( group->GetGroupDS() );
if ( !groupDS ) 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;
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_Group* oldGroup = gOldNew->first;
if ( oldGroup->SMDSGroup().Contains( sourceElem )) // sourceElem in oldGroup
{
SMDS_MeshGroup* & newGroup = gOldNew->second;
if ( !newGroup )// create a new group
{
// make a name
string name = oldGroup->GetStoreName();
name += "_";
name += postfix;
int nb = 0;
while ( !groupNames.insert( name ).second ) // name exists
{
if ( nb == 0 ) {
name += "_1";
}
else {
TCollection_AsciiString nbStr(++nb);
name.resize( name.rfind('_') );
name += nbStr.ToCString();
}
}
// make a group
int id;
SMESH_Group* group = GetMesh()->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;
}
//=======================================================================
@ -6337,7 +6576,7 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode* theBetweenNode
*/
//=======================================================================
int SMESH_MeshEditor::ConvertElemToQuadratic(SMESHDS_SubMesh * theSm,
int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm,
SMESH_MesherHelper& theHelper,
const bool theForce3d)
{
@ -6441,7 +6680,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(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);
}
}
}
@ -6552,7 +6791,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
*/
//=======================================================================
int SMESH_MeshEditor::RemoveQuadElem(SMESHDS_SubMesh * theSm,
int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh * theSm,
SMDS_ElemIteratorPtr theItr,
const int theShapeID)
{
@ -6627,7 +6866,7 @@ bool SMESH_MeshEditor::ConvertFromQuadratic()
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() );
}
}
}
@ -6637,7 +6876,7 @@ bool SMESH_MeshEditor::ConvertFromQuadratic()
if ( nbCheckedElems < totalNbElems ) // not all elements in submeshes
{
SMESHDS_SubMesh *aSM = 0;
RemoveQuadElem( aSM, GetMeshDS()->elementsIterator(), 0 );
removeQuadElem( aSM, GetMeshDS()->elementsIterator(), 0 );
}
return true;

View File

@ -190,13 +190,15 @@ public:
// If the2D, smoothing is performed using UV parameters of nodes
// on geometrical faces
typedef std::auto_ptr< std::list<int> > PGroupIDs;
void RotationSweep (TIDSortedElemSet & theElements,
const gp_Ax1& theAxis,
const double theAngle,
const int theNbSteps,
const double theToler,
const bool theMakeWalls=true);
PGroupIDs RotationSweep (TIDSortedElemSet & theElements,
const gp_Ax1& theAxis,
const double theAngle,
const int theNbSteps,
const double theToler,
const bool theMakeGroups,
const bool theMakeWalls=true);
// Generate new elements by rotation of theElements around theAxis
// by theAngle by theNbSteps
@ -241,13 +243,13 @@ public:
* param theTolerance - uses for comparing locations of nodes if flag
* EXTRUSION_FLAG_SEW is set
*/
void ExtrusionSweep
(TIDSortedElemSet & theElems,
const gp_Vec& theStep,
const int theNbSteps,
TElemOfElemListMap& newElemsMap,
const int theFlags = EXTRUSION_FLAG_BOUNDARY,
const double theTolerance = 1.e-6);
PGroupIDs ExtrusionSweep (TIDSortedElemSet & theElems,
const gp_Vec& theStep,
const int theNbSteps,
TElemOfElemListMap& newElemsMap,
const bool theMakeGroups,
const int theFlags = EXTRUSION_FLAG_BOUNDARY,
const double theTolerance = 1.e-6);
/*!
* Generate new elements by extrusion of theElements
@ -259,11 +261,12 @@ public:
* EXTRUSION_FLAG_SEW is set
* param theParams - special structure for manage of extrusion
*/
void ExtrusionSweep (TIDSortedElemSet & theElems,
ExtrusParam& theParams,
TElemOfElemListMap& newElemsMap,
const int theFlags,
const double theTolerance);
PGroupIDs ExtrusionSweep (TIDSortedElemSet & theElems,
ExtrusParam& theParams,
TElemOfElemListMap& newElemsMap,
const bool theMakeGroups,
const int theFlags,
const double theTolerance);
// Generate new elements by extrusion of theElements
@ -285,13 +288,15 @@ public:
const bool theHasAngles,
std::list<double>& theAngles,
const bool theHasRefPoint,
const gp_Pnt& theRefPoint);
const gp_Pnt& theRefPoint,
const bool theMakeGroups);
// Generate new elements by extrusion of theElements along path given by theTrackPattern,
// theHasAngles are the rotation angles, base point can be given by theRefPoint
void Transform (TIDSortedElemSet & theElements,
const gp_Trsf& theTrsf,
const bool theCopy);
PGroupIDs Transform (TIDSortedElemSet & theElements,
const gp_Trsf& theTrsf,
const bool theCopy,
const bool theMakeGroups);
// Move or copy theElements applying theTrsf to their nodes
typedef std::list< std::list< const SMDS_MeshNode* > > TListOfListOfNodes;
@ -507,7 +512,7 @@ private:
* \brief Convert elements contained in a submesh to quadratic
* \retval int - nb of checked elements
*/
int ConvertElemToQuadratic(SMESHDS_SubMesh * theSm,
int convertElemToQuadratic(SMESHDS_SubMesh * theSm,
SMESH_MesherHelper& theHelper,
const bool theForce3d);
@ -515,11 +520,54 @@ private:
* \brief Convert quadratic elements to linear ones and remove quadratic nodes
* \retval int - nb of checked elements
*/
int RemoveQuadElem( SMESHDS_SubMesh * theSm,
int removeQuadElem( SMESHDS_SubMesh * theSm,
SMDS_ElemIteratorPtr theItr,
const int theShapeID);
//Auxiliary function for "ConvertFromQuadratic" is intended to
/*!
* \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
*/
PGroupIDs generateGroups(const SMESH_SequenceOfElemPtr& nodeGens,
const SMESH_SequenceOfElemPtr& elemGens,
const std::string& postfix);
typedef std::map<const SMDS_MeshNode*, std::list<const SMDS_MeshNode*> > TNodeOfNodeListMap;
typedef TNodeOfNodeListMap::iterator TNodeOfNodeListMapItr;
typedef std::vector<TNodeOfNodeListMapItr> TVecOfNnlmiMap;
typedef std::map<const SMDS_MeshElement*, TVecOfNnlmiMap > TElemOfVecOfNnlmiMap;
/*!
* \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
*/
void sweepElement(const SMDS_MeshElement* elem,
const std::vector<TNodeOfNodeListMapItr> & newNodesItVec,
std::list<const SMDS_MeshElement*>& newElems,
const int nbSteps,
SMESH_SequenceOfElemPtr& srcElements);
/*!
* \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
*/
void makeWalls (TNodeOfNodeListMap & mapNewNodes,
TElemOfElemListMap & newElemsMap,
TElemOfVecOfNnlmiMap & elemNewNodesMap,
TIDSortedElemSet& elemSet,
const int nbSteps,
SMESH_SequenceOfElemPtr& srcElements);
private:
SMESH_Mesh * myMesh;