#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"
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 {
}
//=======================================================================
-//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();
}
// 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;
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 ) {
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)
{
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();
// 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> iter_isnew =
+ nodeMap.insert( make_pair ( node, node ));
+ if ( !iter_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] );
+ 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] );
const_cast< SMDS_MeshNode* > ( node )->SetPosition
( SMDS_SpacePosition::originSpacePosition() );
}
- nodeMap.insert( make_pair( node, newNode ));
// keep inverse elements
if ( !theCopy && needReverse ) {
}
}
- // 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
{ 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 ( 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 ( theCopy ) {
myLastCreatedElems.Append(aMesh->AddPolyhedralVolume(poly_nodes, quantities));
+ srcElems.Append( elem );
}
else {
aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
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
{
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;
}
//=======================================================================
*/
//=======================================================================
-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)
{
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;