-// SMESH SMESH : idl implementation based on 'SMESH' unit's classes
+// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// This library is free software; you can redistribute it and/or
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+// SMESH SMESH : idl implementation based on 'SMESH' unit's classes
// File : SMESH_MeshEditor.cxx
// Created : Mon Apr 12 16:10:22 2004
// Author : Edward AGAPOV (eap)
-
-
+//
#include "SMESH_MeshEditor.hxx"
#include "SMDS_FaceOfNodes.hxx"
#include "utilities.h"
#include <BRep_Tool.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
#include <ElCLib.hxx>
#include <Extrema_GenExtPS.hxx>
#include <Extrema_POnSurf.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Surface.hxx>
+#include <Precision.hxx>
#include <TColStd_ListOfInteger.hxx>
+#include <TopAbs_State.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <gp.hxx>
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 :
SMESHDS_Mesh * aMesh)
{
const set<SMESHDS_GroupBase*>& groups = aMesh->GetGroups();
- set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
- for ( ; grIt != groups.end(); grIt++ ) {
- SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *grIt );
- if ( group && group->Contains( elemInGroups ))
- group->SMDSGroup().Add( elemToAdd );
+ if (!groups.empty()) {
+ set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
+ for ( ; grIt != groups.end(); grIt++ ) {
+ SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *grIt );
+ if ( group && group->Contains( elemInGroups ))
+ group->SMDSGroup().Add( elemToAdd );
+ }
}
}
}
}
+//=======================================================================
+//function : ReplaceElemInGroups
+//purpose : replace elemToRm by elemToAdd in the all groups
+//=======================================================================
+
+void SMESH_MeshEditor::ReplaceElemInGroups (const SMDS_MeshElement* elemToRm,
+ const SMDS_MeshElement* elemToAdd,
+ SMESHDS_Mesh * aMesh)
+{
+ const set<SMESHDS_GroupBase*>& groups = aMesh->GetGroups();
+ if (!groups.empty()) {
+ set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
+ for ( ; grIt != groups.end(); grIt++ ) {
+ SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *grIt );
+ if ( group && group->SMDSGroup().Remove( elemToRm ) && elemToAdd )
+ group->SMDSGroup().Add( elemToAdd );
+ }
+ }
+}
//=======================================================================
//function : QuadToTri
// 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 );
}
iAfter = SMESH_MesherHelper::WrapIndex( iAfter, nb );
iBefore = SMESH_MesherHelper::WrapIndex( iBefore, nb );
}
- linkedNodes.insert( elem->GetNode( iAfter ));
- linkedNodes.insert( elem->GetNode( iBefore ));
+ linkedNodes.insert( elem->GetNodeWrap( iAfter ));
+ linkedNodes.insert( elem->GetNodeWrap( iBefore ));
}
}
}
// 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 ) {
if(elem->IsQuadratic())
nbn = nbn/2;
// loop on elem links: insert them in linkNbMap
- const SMDS_MeshNode* curNode, *prevNode = elem->GetNode( nbn );
+ const SMDS_MeshNode* curNode, *prevNode = elem->GetNodeWrap( 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;
int iNode, nbSame = 0, iNotSameNode = 0, iSameNode = 0;
vector<int> sames(nbNodes);
-
- //bool issimple[nbNodes];
vector<bool> issimple(nbNodes);
for ( iNode = 0; iNode < nbNodes; iNode++ ) {
TNodeOfNodeListMapItr nnIt = newNodesItVec[ iNode ];
const SMDS_MeshNode* node = nnIt->first;
const list< const SMDS_MeshNode* > & listNewNodes = nnIt->second;
- if ( listNewNodes.empty() )
+ if ( listNewNodes.empty() ) {
return;
-
- if(listNewNodes.size()==nbSteps) {
- issimple[iNode] = true;
- }
- else {
- issimple[iNode] = false;
}
+ issimple[iNode] = (listNewNodes.size()==nbSteps);
+
itNN[ iNode ] = listNewNodes.begin();
prevNod[ iNode ] = node;
nextNod[ iNode ] = listNewNodes.front();
-//cout<<"iNode="<<iNode<<endl;
-//cout<<" prevNod[iNode]="<< prevNod[iNode]<<" nextNod[iNode]="<< nextNod[iNode]<<endl;
- if ( prevNod[ iNode ] != nextNod [ iNode ])
- iNotSameNode = iNode;
- else {
- iSameNode = iNode;
- //nbSame++;
- sames[nbSame++] = iNode;
+ if( !issimple[iNode] ) {
+ if ( prevNod[ iNode ] != nextNod [ iNode ])
+ iNotSameNode = iNode;
+ else {
+ iSameNode = iNode;
+ //nbSame++;
+ sames[nbSame++] = iNode;
+ }
}
}
-//cout<<"1 nbSame="<<nbSame<<endl;
+
+ //cout<<" nbSame = "<<nbSame<<endl;
if ( nbSame == nbNodes || nbSame > 2) {
- MESSAGE( " Too many same nodes of element " << elem->GetID() );
+ //MESSAGE( " Too many same nodes of element " << elem->GetID() );
+ INFOS( " Too many same nodes of element " << elem->GetID() );
return;
}
// }
int iBeforeSame = 0, iAfterSame = 0, iOpposSame = 0;
+ int nbBaseNodes = ( elem->IsQuadratic() ? nbNodes/2 : nbNodes );
if ( nbSame > 0 ) {
- iBeforeSame = ( iSameNode == 0 ? nbNodes - 1 : iSameNode - 1 );
- iAfterSame = ( iSameNode + 1 == nbNodes ? 0 : iSameNode + 1 );
+ iBeforeSame = ( iSameNode == 0 ? nbBaseNodes - 1 : iSameNode - 1 );
+ iAfterSame = ( iSameNode + 1 == nbBaseNodes ? 0 : iSameNode + 1 );
iOpposSame = ( iSameNode - 2 < 0 ? iSameNode + 2 : iSameNode - 2 );
}
//MESSAGE("Reversed elem " << elem );
i0 = 2;
i2 = 0;
- if ( nbSame > 0 ) {
- int iAB = iAfterSame + iBeforeSame;
- iBeforeSame = iAB - iBeforeSame;
- iAfterSame = iAB - iAfterSame;
- }
+ if ( nbSame > 0 )
+ std::swap( iBeforeSame, iAfterSame );
}
// make new elements
nextNod[ iNode ] = *itNN[ iNode ];
itNN[ iNode ]++;
}
- else if(!elem->IsQuadratic() ||
- elem->IsQuadratic() && elem->IsMediumNode(prevNod[iNode]) ) {
+ else if(!elem->IsQuadratic() || elem->IsMediumNode(prevNod[iNode]) ) {
// we have to use each second node
- itNN[ iNode ]++;
+ //itNN[ iNode ]++;
nextNod[ iNode ] = *itNN[ iNode ];
itNN[ iNode ]++;
}
midlNod[0], nextNod[2], midlNod[1], prevNod[2]);
}
else if(nbSame==1) { // quadratic triangle
- if(sames[0]==2)
+ if(sames[0]==2) {
return; // medium node on axis
+ }
else if(sames[0]==0) {
aNewElem = aMesh->AddFace(prevNod[0], nextNod[1], prevNod[1],
nextNod[2], midlNod[1], prevNod[2]);
midlNod[0], nextNod[2], prevNod[2]);
}
}
- else
+ else {
return;
+ }
}
break;
}
}
case 6: { // quadratic triangle
// create pentahedron with 15 nodes
- if(i0>0) { // reversed case
- aNewElem = aMesh->AddVolume (prevNod[0], prevNod[2], prevNod[1],
- nextNod[0], nextNod[2], nextNod[1],
- prevNod[5], prevNod[4], prevNod[3],
- nextNod[5], nextNod[4], nextNod[3],
- midlNod[0], midlNod[2], midlNod[1]);
- }
- else { // not reversed case
- aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2],
- nextNod[0], nextNod[1], nextNod[2],
- prevNod[3], prevNod[4], prevNod[5],
- nextNod[3], nextNod[4], nextNod[5],
- midlNod[0], midlNod[1], midlNod[2]);
- }
+ if(nbSame==0) {
+ if(i0>0) { // reversed case
+ aNewElem = aMesh->AddVolume (prevNod[0], prevNod[2], prevNod[1],
+ nextNod[0], nextNod[2], nextNod[1],
+ prevNod[5], prevNod[4], prevNod[3],
+ nextNod[5], nextNod[4], nextNod[3],
+ midlNod[0], midlNod[2], midlNod[1]);
+ }
+ else { // not reversed case
+ aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2],
+ nextNod[0], nextNod[1], nextNod[2],
+ prevNod[3], prevNod[4], prevNod[5],
+ nextNod[3], nextNod[4], nextNod[5],
+ midlNod[0], midlNod[1], midlNod[2]);
+ }
+ }
+ else if(nbSame==1) {
+ // 2d order pyramid of 13 nodes
+ //SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
+ // int n12,int n23,int n34,int n41,
+ // int n15,int n25,int n35,int n45, int ID);
+ int n5 = iSameNode;
+ int n1,n4,n41,n15,n45;
+ if(i0>0) { // reversed case
+ n1 = ( n5 + 1 == nbBaseNodes ? 0 : n5 + 1 );
+ n4 = ( n5 == 0 ? nbBaseNodes - 1 : n5 - 1 );
+ n41 = n1 + 3;
+ n15 = n5 + 3;
+ n45 = n4 + 3;
+ }
+ else {
+ n1 = ( n5 == 0 ? nbBaseNodes - 1 : n5 - 1 );
+ n4 = ( n5 + 1 == nbBaseNodes ? 0 : n5 + 1 );
+ n41 = n4 + 3;
+ n15 = n1 + 3;
+ n45 = n5 + 3;
+ }
+ aNewElem = aMesh->AddVolume(prevNod[n1], nextNod[n1],
+ nextNod[n4], prevNod[n4], prevNod[n5],
+ midlNod[n1], nextNod[n41],
+ midlNod[n4], prevNod[n41],
+ prevNod[n15], nextNod[n15],
+ nextNod[n45], prevNod[n45]);
+ }
+ else if(nbSame==2) {
+ // 2d order tetrahedron of 10 nodes
+ //SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
+ // int n12,int n23,int n31,
+ // int n14,int n24,int n34, int ID);
+ int n1 = iNotSameNode;
+ int n2,n3,n12,n23,n31;
+ if(i0>0) { // reversed case
+ n2 = ( n1 == 0 ? nbBaseNodes - 1 : n1 - 1 );
+ n3 = ( n1 + 1 == nbBaseNodes ? 0 : n1 + 1 );
+ n12 = n2 + 3;
+ n23 = n3 + 3;
+ n31 = n1 + 3;
+ }
+ else {
+ n2 = ( n1 + 1 == nbBaseNodes ? 0 : n1 + 1 );
+ n3 = ( n1 == 0 ? nbBaseNodes - 1 : n1 - 1 );
+ n12 = n1 + 3;
+ n23 = n2 + 3;
+ n31 = n3 + 3;
+ }
+ aNewElem = aMesh->AddVolume (prevNod[n1], prevNod[n2], prevNod[n3], nextNod[n1],
+ prevNod[n12], prevNod[n23], prevNod[n31],
+ midlNod[n1], nextNod[n12], nextNod[n31]);
+ }
break;
}
case 8: { // quadratic quadrangle
- // create hexahedron with 20 nodes
- if(i0>0) { // reversed case
- aNewElem = aMesh->AddVolume (prevNod[0], prevNod[3], prevNod[2], prevNod[1],
- nextNod[0], nextNod[3], nextNod[2], nextNod[1],
- prevNod[7], prevNod[6], prevNod[5], prevNod[4],
- nextNod[7], nextNod[6], nextNod[5], nextNod[4],
- midlNod[0], midlNod[3], midlNod[2], midlNod[1]);
- }
- else { // not reversed case
- aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2], prevNod[3],
- nextNod[0], nextNod[1], nextNod[2], nextNod[3],
- prevNod[4], prevNod[5], prevNod[6], prevNod[7],
- nextNod[4], nextNod[5], nextNod[6], nextNod[7],
- midlNod[0], midlNod[1], midlNod[2], midlNod[3]);
- }
+ if(nbSame==0) {
+ // create hexahedron with 20 nodes
+ if(i0>0) { // reversed case
+ aNewElem = aMesh->AddVolume (prevNod[0], prevNod[3], prevNod[2], prevNod[1],
+ nextNod[0], nextNod[3], nextNod[2], nextNod[1],
+ prevNod[7], prevNod[6], prevNod[5], prevNod[4],
+ nextNod[7], nextNod[6], nextNod[5], nextNod[4],
+ midlNod[0], midlNod[3], midlNod[2], midlNod[1]);
+ }
+ else { // not reversed case
+ aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2], prevNod[3],
+ nextNod[0], nextNod[1], nextNod[2], nextNod[3],
+ prevNod[4], prevNod[5], prevNod[6], prevNod[7],
+ nextNod[4], nextNod[5], nextNod[6], nextNod[7],
+ midlNod[0], midlNod[1], midlNod[2], midlNod[3]);
+ }
+ }
+ else if(nbSame==1) {
+ // --- pyramid + pentahedron - can not be created since it is needed
+ // additional middle node ot the center of face
+ INFOS( " Sweep for face " << elem->GetID() << " can not be created" );
+ return;
+ }
+ else if(nbSame==2) {
+ // 2d order Pentahedron with 15 nodes
+ //SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6,
+ // int n12,int n23,int n31,int n45,int n56,int n64,
+ // int n14,int n25,int n36, int ID);
+ int n1,n2,n4,n5;
+ if ( prevNod[ iBeforeSame ] == nextNod[ iBeforeSame ] ) {
+ // iBeforeSame is same too
+ n1 = iBeforeSame;
+ n2 = iOpposSame;
+ n4 = iSameNode;
+ n5 = iAfterSame;
+ }
+ else {
+ // iAfterSame is same too
+ n1 = iSameNode;
+ n2 = iBeforeSame;
+ n4 = iAfterSame;
+ n5 = iOpposSame;
+ }
+ int n12,n45,n14,n25;
+ if(i0>0) { //reversed case
+ n12 = n1 + 4;
+ n45 = n5 + 4;
+ n14 = n4 + 4;
+ n25 = n2 + 4;
+ }
+ else {
+ n12 = n2 + 4;
+ n45 = n4 + 4;
+ n14 = n1 + 4;
+ n25 = n5 + 4;
+ }
+ aNewElem = aMesh->AddVolume (prevNod[n1], prevNod[n2], nextNod[n2],
+ prevNod[n4], prevNod[n5], nextNod[n5],
+ prevNod[n12], midlNod[n2], nextNod[n12],
+ prevNod[n45], midlNod[n5], nextNod[n45],
+ prevNod[n14], prevNod[n25], nextNod[n25]);
+ }
break;
}
default: {
const SMDS_MeshFace * f = aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ]);
if ( !f )
myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ));
- else if ( nodes[ 1 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 ))
+ else if ( nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 ))
aMesh->ChangeElementNodes( f, nodes, nbn );
break;
}
const SMDS_MeshFace * f = aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ]);
if ( !f )
myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] ));
- else if ( nodes[ 1 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 ))
+ else if ( nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 ))
aMesh->ChangeElementNodes( f, nodes, nbn );
break;
}
if(nbn==6) { /////// quadratic triangle
const SMDS_MeshFace * f = aMesh->FindFace( nodes[0], nodes[2], nodes[4],
nodes[1], nodes[3], nodes[5] );
- if ( !f )
+ if ( !f ) {
myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4],
nodes[1], nodes[3], nodes[5]));
- else if ( nodes[ 2 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 ))
- aMesh->ChangeElementNodes( f, nodes, nbn );
+ }
+ else if ( nodes[ 2 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) {
+ const SMDS_MeshNode** tmpnodes = new const SMDS_MeshNode*[6];
+ tmpnodes[0] = nodes[0];
+ tmpnodes[1] = nodes[2];
+ tmpnodes[2] = nodes[4];
+ tmpnodes[3] = nodes[1];
+ tmpnodes[4] = nodes[3];
+ tmpnodes[5] = nodes[5];
+ aMesh->ChangeElementNodes( f, tmpnodes, nbn );
+ }
}
else { /////// quadratic quadrangle
const SMDS_MeshFace * f = aMesh->FindFace( nodes[0], nodes[2], nodes[4], nodes[6],
nodes[1], nodes[3], nodes[5], nodes[7] );
- if ( !f )
+ if ( !f ) {
myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6],
nodes[1], nodes[3], nodes[5], nodes[7]));
- else if ( nodes[ 2 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 ))
- aMesh->ChangeElementNodes( f, nodes, nbn );
+ }
+ else if ( nodes[ 2 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) {
+ const SMDS_MeshNode** tmpnodes = new const SMDS_MeshNode*[8];
+ tmpnodes[0] = nodes[0];
+ tmpnodes[1] = nodes[2];
+ tmpnodes[2] = nodes[4];
+ tmpnodes[3] = nodes[6];
+ tmpnodes[4] = nodes[1];
+ tmpnodes[5] = nodes[3];
+ tmpnodes[6] = nodes[5];
+ tmpnodes[7] = nodes[7];
+ aMesh->ChangeElementNodes( f, tmpnodes, nbn );
+ }
}
}
else { //////// polygon
const SMDS_MeshFace * f = aMesh->FindFace( polygon_nodes );
if ( !f )
myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes));
- else if ( nodes[ 1 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 ))
+ else if ( nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 ))
aMesh->ChangeElementNodes( f, nodes, nbn );
}
}
// 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 = cast2Node( itN->next() );
+
+ gp_XYZ aXYZ( node->X(), node->Y(), node->Z() );
+ double coord[3];
+ aXYZ.Coord( coord[0], coord[1], coord[2] );
+ bool isOnAxis = ( aLine.SquareDistance( aXYZ ) <= aSqTol );
+
TNodeOfNodeListMapItr nIt = mapNewNodes.find( node );
if ( nIt == mapNewNodes.end() ) {
nIt = mapNewNodes.insert( make_pair( node, list<const SMDS_MeshNode*>() )).first;
list<const SMDS_MeshNode*>& listNewNodes = nIt->second;
// make new nodes
- gp_XYZ aXYZ( node->X(), node->Y(), node->Z() );
- double coord[3];
- aXYZ.Coord( coord[0], coord[1], coord[2] );
- bool isOnAxis = ( aLine.SquareDistance( aXYZ ) <= aSqTol );
+ //gp_XYZ aXYZ( node->X(), node->Y(), node->Z() );
+ //double coord[3];
+ //aXYZ.Coord( coord[0], coord[1], coord[2] );
+ //bool isOnAxis = ( aLine.SquareDistance( aXYZ ) <= aSqTol );
const SMDS_MeshNode * newNode = node;
for ( int i = 0; i < theNbSteps; i++ ) {
if ( !isOnAxis ) {
newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
myLastCreatedNodes.Append(newNode);
srcNodes.Append( node );
+ listNewNodes.push_back( newNode );
}
- listNewNodes.push_back( newNode );
+ else {
+ listNewNodes.push_back( newNode );
+ if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
+ listNewNodes.push_back( newNode );
+ }
+ }
}
}
+ /*
else {
// if current elem is quadratic and current node is not medium
// we have to check - may be it is needed to insert additional nodes
if(listNewNodes.size()==theNbSteps) {
listNewNodes.clear();
// make new nodes
- gp_XYZ aXYZ( node->X(), node->Y(), node->Z() );
- double coord[3];
- aXYZ.Coord( coord[0], coord[1], coord[2] );
+ //gp_XYZ aXYZ( node->X(), node->Y(), node->Z() );
+ //double coord[3];
+ //aXYZ.Coord( coord[0], coord[1], coord[2] );
const SMDS_MeshNode * newNode = node;
- for(int i = 0; i<theNbSteps; i++) {
- aTrsf2.Transforms( coord[0], coord[1], coord[2] );
- newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
- myLastCreatedNodes.Append(newNode);
- listNewNodes.push_back( newNode );
- 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 );
+ if ( !isOnAxis ) {
+ for(int i = 0; i<theNbSteps; i++) {
+ aTrsf2.Transforms( coord[0], coord[1], coord[2] );
+ newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+ cout<<" 3 AddNode: "<<newNode;
+ 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] );
+ cout<<" 4 AddNode: "<<newNode;
+ myLastCreatedNodes.Append(newNode);
+ srcNodes.Append( node );
+ listNewNodes.push_back( newNode );
+ }
}
+ else {
+ listNewNodes.push_back( newNode );
+ }
}
}
}
+ */
newNodesItVec.push_back( nIt );
}
// make new elements
return newGroupIDs;
}
-
+/*
//=======================================================================
//class : SMESH_MeshEditor_PathPoint
//purpose : auxiliary class
double myAngle;
double myPrm;
};
+*/
//=======================================================================
//function : ExtrusionAlongTrack
const SMDS_MeshNode* theN1,
const bool theHasAngles,
list<double>& theAngles,
+ const bool theLinearVariation,
const bool theHasRefPoint,
const gp_Pnt& theRefPoint,
const bool theMakeGroups)
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
- // source elements for each generated one
- SMESH_SequenceOfElemPtr srcElems, srcNodes;
-
- int j, aNbTP, aNbE, aNb;
- double aT1, aT2, aT, aAngle, aX, aY, aZ;
+ int aNbE;
std::list<double> aPrms;
- std::list<double>::iterator aItD;
TIDSortedElemSet::iterator itElem;
- Standard_Real aTx1, aTx2, aL2, aTolVec, aTolVec2;
- gp_Pnt aP3D, aV0;
- gp_Vec aVec;
gp_XYZ aGC;
- Handle(Geom_Curve) aC3D;
TopoDS_Edge aTrackEdge;
TopoDS_Vertex aV1, aV2;
SMDSAbs_ElementType aTypeE;
TNodeOfNodeListMap mapNewNodes;
- TElemOfVecOfNnlmiMap mapElemNewNodes;
- TElemOfElemListMap newElemsMap;
-
- aTolVec=1.e-7;
- aTolVec2=aTolVec*aTolVec;
// 1. Check data
aNbE = theElements.size();
// 1.1 Track Pattern
ASSERT( theTrack );
- SMESHDS_SubMesh* pSubMeshDS=theTrack->GetSubMeshDS();
+ SMESHDS_SubMesh* pSubMeshDS = theTrack->GetSubMeshDS();
aItE = pSubMeshDS->GetElements();
while ( aItE->more() ) {
return EXTR_PATH_NOT_EDGE;
}
+ list<SMESH_MeshEditor_PathPoint> fullList;
+
const TopoDS_Shape& aS = theTrack->GetSubShape();
- // Sub shape for the Pattern must be an Edge
- if ( aS.ShapeType() != TopAbs_EDGE )
+ // Sub shape for the Pattern must be an Edge or Wire
+ if( aS.ShapeType() == TopAbs_EDGE ) {
+ aTrackEdge = TopoDS::Edge( aS );
+ // the Edge must not be degenerated
+ if ( BRep_Tool::Degenerated( aTrackEdge ) )
+ return EXTR_BAD_PATH_SHAPE;
+ TopExp::Vertices( aTrackEdge, aV1, aV2 );
+ aItN = theTrack->GetFather()->GetSubMesh( aV1 )->GetSubMeshDS()->GetNodes();
+ const SMDS_MeshNode* aN1 = aItN->next();
+ aItN = theTrack->GetFather()->GetSubMesh( aV2 )->GetSubMeshDS()->GetNodes();
+ const SMDS_MeshNode* aN2 = aItN->next();
+ // starting node must be aN1 or aN2
+ if ( !( aN1 == theN1 || aN2 == theN1 ) )
+ return EXTR_BAD_STARTING_NODE;
+ aItN = pSubMeshDS->GetNodes();
+ while ( aItN->more() ) {
+ const SMDS_MeshNode* pNode = aItN->next();
+ const SMDS_EdgePosition* pEPos =
+ static_cast<const SMDS_EdgePosition*>( pNode->GetPosition().get() );
+ double aT = pEPos->GetUParameter();
+ aPrms.push_back( aT );
+ }
+ //Extrusion_Error err =
+ MakeEdgePathPoints(aPrms, aTrackEdge, (aN1==theN1), fullList);
+ }
+ else if( aS.ShapeType() == TopAbs_WIRE ) {
+ list< SMESH_subMesh* > LSM;
+ TopTools_SequenceOfShape Edges;
+ SMESH_subMeshIteratorPtr itSM = theTrack->getDependsOnIterator(false,true);
+ while(itSM->more()) {
+ SMESH_subMesh* SM = itSM->next();
+ LSM.push_back(SM);
+ const TopoDS_Shape& aS = SM->GetSubShape();
+ Edges.Append(aS);
+ }
+ list< list<SMESH_MeshEditor_PathPoint> > LLPPs;
+ int startNid = theN1->GetID();
+ TColStd_MapOfInteger UsedNums;
+ int NbEdges = Edges.Length();
+ int i = 1;
+ for(; i<=NbEdges; i++) {
+ int k = 0;
+ list< SMESH_subMesh* >::iterator itLSM = LSM.begin();
+ for(; itLSM!=LSM.end(); itLSM++) {
+ k++;
+ if(UsedNums.Contains(k)) continue;
+ aTrackEdge = TopoDS::Edge( Edges.Value(k) );
+ SMESH_subMesh* locTrack = *itLSM;
+ SMESHDS_SubMesh* locMeshDS = locTrack->GetSubMeshDS();
+ TopExp::Vertices( aTrackEdge, aV1, aV2 );
+ aItN = locTrack->GetFather()->GetSubMesh(aV1)->GetSubMeshDS()->GetNodes();
+ const SMDS_MeshNode* aN1 = aItN->next();
+ aItN = locTrack->GetFather()->GetSubMesh(aV2)->GetSubMeshDS()->GetNodes();
+ const SMDS_MeshNode* aN2 = aItN->next();
+ // starting node must be aN1 or aN2
+ if ( !( aN1->GetID() == startNid || aN2->GetID() == startNid ) ) continue;
+ // 2. Collect parameters on the track edge
+ aPrms.clear();
+ aItN = locMeshDS->GetNodes();
+ while ( aItN->more() ) {
+ const SMDS_MeshNode* pNode = aItN->next();
+ const SMDS_EdgePosition* pEPos =
+ static_cast<const SMDS_EdgePosition*>( pNode->GetPosition().get() );
+ double aT = pEPos->GetUParameter();
+ aPrms.push_back( aT );
+ }
+ list<SMESH_MeshEditor_PathPoint> LPP;
+ //Extrusion_Error err =
+ MakeEdgePathPoints(aPrms, aTrackEdge,(aN1->GetID()==startNid), LPP);
+ LLPPs.push_back(LPP);
+ UsedNums.Add(k);
+ // update startN for search following egde
+ if( aN1->GetID() == startNid ) startNid = aN2->GetID();
+ else startNid = aN1->GetID();
+ break;
+ }
+ }
+ list< list<SMESH_MeshEditor_PathPoint> >::iterator itLLPP = LLPPs.begin();
+ list<SMESH_MeshEditor_PathPoint> firstList = *itLLPP;
+ list<SMESH_MeshEditor_PathPoint>::iterator itPP = firstList.begin();
+ for(; itPP!=firstList.end(); itPP++) {
+ fullList.push_back( *itPP );
+ }
+ SMESH_MeshEditor_PathPoint PP1 = fullList.back();
+ fullList.pop_back();
+ itLLPP++;
+ for(; itLLPP!=LLPPs.end(); itLLPP++) {
+ list<SMESH_MeshEditor_PathPoint> currList = *itLLPP;
+ itPP = currList.begin();
+ SMESH_MeshEditor_PathPoint PP2 = currList.front();
+ gp_Dir D1 = PP1.Tangent();
+ gp_Dir D2 = PP2.Tangent();
+ gp_Dir Dnew( gp_Vec( (D1.X()+D2.X())/2, (D1.Y()+D2.Y())/2,
+ (D1.Z()+D2.Z())/2 ) );
+ PP1.SetTangent(Dnew);
+ fullList.push_back(PP1);
+ itPP++;
+ for(; itPP!=firstList.end(); itPP++) {
+ fullList.push_back( *itPP );
+ }
+ PP1 = fullList.back();
+ fullList.pop_back();
+ }
+ // if wire not closed
+ fullList.push_back(PP1);
+ // else ???
+ }
+ else {
return EXTR_BAD_PATH_SHAPE;
+ }
- aTrackEdge = TopoDS::Edge( aS );
- // the Edge must not be degenerated
- if ( BRep_Tool::Degenerated( aTrackEdge ) )
- return EXTR_BAD_PATH_SHAPE;
+ return MakeExtrElements(theElements, fullList, theHasAngles, theAngles, theLinearVariation,
+ theHasRefPoint, theRefPoint, theMakeGroups);
+}
- TopExp::Vertices( aTrackEdge, aV1, aV2 );
- aT1=BRep_Tool::Parameter( aV1, aTrackEdge );
- aT2=BRep_Tool::Parameter( aV2, aTrackEdge );
- aItN = theTrack->GetFather()->GetSubMesh( aV1 )->GetSubMeshDS()->GetNodes();
- const SMDS_MeshNode* aN1 = aItN->next();
+//=======================================================================
+//function : ExtrusionAlongTrack
+//purpose :
+//=======================================================================
+SMESH_MeshEditor::Extrusion_Error
+ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet & theElements,
+ SMESH_Mesh* theTrack,
+ const SMDS_MeshNode* theN1,
+ const bool theHasAngles,
+ list<double>& theAngles,
+ const bool theLinearVariation,
+ const bool theHasRefPoint,
+ const gp_Pnt& theRefPoint,
+ const bool theMakeGroups)
+{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
+ int aNbE;
+ std::list<double> aPrms;
+ TIDSortedElemSet::iterator itElem;
- aItN = theTrack->GetFather()->GetSubMesh( aV2 )->GetSubMeshDS()->GetNodes();
- const SMDS_MeshNode* aN2 = aItN->next();
+ gp_XYZ aGC;
+ TopoDS_Edge aTrackEdge;
+ TopoDS_Vertex aV1, aV2;
- // starting node must be aN1 or aN2
- if ( !( aN1 == theN1 || aN2 == theN1 ) )
- return EXTR_BAD_STARTING_NODE;
+ SMDS_ElemIteratorPtr aItE;
+ SMDS_NodeIteratorPtr aItN;
+ SMDSAbs_ElementType aTypeE;
- aNbTP = pSubMeshDS->NbNodes() + 2;
+ TNodeOfNodeListMap mapNewNodes;
- // 1.2. Angles
- vector<double> aAngles( aNbTP );
+ // 1. Check data
+ aNbE = theElements.size();
+ // nothing to do
+ if ( !aNbE )
+ return EXTR_NO_ELEMENTS;
- for ( j=0; j < aNbTP; ++j ) {
- aAngles[j] = 0.;
+ // 1.1 Track Pattern
+ ASSERT( theTrack );
+
+ SMESHDS_Mesh* pMeshDS = theTrack->GetMeshDS();
+
+ aItE = pMeshDS->elementsIterator();
+ while ( aItE->more() ) {
+ const SMDS_MeshElement* pE = aItE->next();
+ aTypeE = pE->GetType();
+ // Pattern must contain links only
+ if ( aTypeE != SMDSAbs_Edge )
+ return EXTR_PATH_NOT_EDGE;
}
- if ( theHasAngles ) {
- aItD = theAngles.begin();
- for ( j=1; (aItD != theAngles.end()) && (j<aNbTP); ++aItD, ++j ) {
- aAngle = *aItD;
- aAngles[j] = aAngle;
+ list<SMESH_MeshEditor_PathPoint> fullList;
+
+ const TopoDS_Shape& aS = theTrack->GetShapeToMesh();
+ // Sub shape for the Pattern must be an Edge or Wire
+ if( aS.ShapeType() == TopAbs_EDGE ) {
+ aTrackEdge = TopoDS::Edge( aS );
+ // the Edge must not be degenerated
+ if ( BRep_Tool::Degenerated( aTrackEdge ) )
+ return EXTR_BAD_PATH_SHAPE;
+ TopExp::Vertices( aTrackEdge, aV1, aV2 );
+ aItN = theTrack->GetSubMesh( aV1 )->GetSubMeshDS()->GetNodes();
+ const SMDS_MeshNode* aN1 = aItN->next();
+ aItN = theTrack->GetSubMesh( aV2 )->GetSubMeshDS()->GetNodes();
+ const SMDS_MeshNode* aN2 = aItN->next();
+ // starting node must be aN1 or aN2
+ if ( !( aN1 == theN1 || aN2 == theN1 ) )
+ return EXTR_BAD_STARTING_NODE;
+ aItN = pMeshDS->nodesIterator();
+ while ( aItN->more() ) {
+ const SMDS_MeshNode* pNode = aItN->next();
+ if( pNode==aN1 || pNode==aN2 ) continue;
+ const SMDS_EdgePosition* pEPos =
+ static_cast<const SMDS_EdgePosition*>( pNode->GetPosition().get() );
+ double aT = pEPos->GetUParameter();
+ aPrms.push_back( aT );
+ }
+ //Extrusion_Error err =
+ MakeEdgePathPoints(aPrms, aTrackEdge, (aN1==theN1), fullList);
+ }
+ else if( aS.ShapeType() == TopAbs_WIRE ) {
+ list< SMESH_subMesh* > LSM;
+ TopTools_SequenceOfShape Edges;
+ TopExp_Explorer eExp(aS, TopAbs_EDGE);
+ for(; eExp.More(); eExp.Next()) {
+ TopoDS_Edge E = TopoDS::Edge( eExp.Current() );
+ if( BRep_Tool::Degenerated(E) ) continue;
+ SMESH_subMesh* SM = theTrack->GetSubMesh(E);
+ if(SM) {
+ LSM.push_back(SM);
+ Edges.Append(E);
+ }
+ }
+ list< list<SMESH_MeshEditor_PathPoint> > LLPPs;
+ int startNid = theN1->GetID();
+ TColStd_MapOfInteger UsedNums;
+ int NbEdges = Edges.Length();
+ int i = 1;
+ for(; i<=NbEdges; i++) {
+ int k = 0;
+ list< SMESH_subMesh* >::iterator itLSM = LSM.begin();
+ for(; itLSM!=LSM.end(); itLSM++) {
+ k++;
+ if(UsedNums.Contains(k)) continue;
+ aTrackEdge = TopoDS::Edge( Edges.Value(k) );
+ SMESH_subMesh* locTrack = *itLSM;
+ SMESHDS_SubMesh* locMeshDS = locTrack->GetSubMeshDS();
+ TopExp::Vertices( aTrackEdge, aV1, aV2 );
+ aItN = locTrack->GetFather()->GetSubMesh(aV1)->GetSubMeshDS()->GetNodes();
+ const SMDS_MeshNode* aN1 = aItN->next();
+ aItN = locTrack->GetFather()->GetSubMesh(aV2)->GetSubMeshDS()->GetNodes();
+ const SMDS_MeshNode* aN2 = aItN->next();
+ // starting node must be aN1 or aN2
+ if ( !( aN1->GetID() == startNid || aN2->GetID() == startNid ) ) continue;
+ // 2. Collect parameters on the track edge
+ aPrms.clear();
+ aItN = locMeshDS->GetNodes();
+ while ( aItN->more() ) {
+ const SMDS_MeshNode* pNode = aItN->next();
+ const SMDS_EdgePosition* pEPos =
+ static_cast<const SMDS_EdgePosition*>( pNode->GetPosition().get() );
+ double aT = pEPos->GetUParameter();
+ aPrms.push_back( aT );
+ }
+ list<SMESH_MeshEditor_PathPoint> LPP;
+ //Extrusion_Error err =
+ MakeEdgePathPoints(aPrms, aTrackEdge,(aN1->GetID()==startNid), LPP);
+ LLPPs.push_back(LPP);
+ UsedNums.Add(k);
+ // update startN for search following egde
+ if( aN1->GetID() == startNid ) startNid = aN2->GetID();
+ else startNid = aN1->GetID();
+ break;
+ }
}
+ list< list<SMESH_MeshEditor_PathPoint> >::iterator itLLPP = LLPPs.begin();
+ list<SMESH_MeshEditor_PathPoint> firstList = *itLLPP;
+ list<SMESH_MeshEditor_PathPoint>::iterator itPP = firstList.begin();
+ for(; itPP!=firstList.end(); itPP++) {
+ fullList.push_back( *itPP );
+ }
+ SMESH_MeshEditor_PathPoint PP1 = fullList.back();
+ fullList.pop_back();
+ itLLPP++;
+ for(; itLLPP!=LLPPs.end(); itLLPP++) {
+ list<SMESH_MeshEditor_PathPoint> currList = *itLLPP;
+ itPP = currList.begin();
+ SMESH_MeshEditor_PathPoint PP2 = currList.front();
+ gp_Pnt P1 = PP1.Pnt();
+ //cout<<" PP1: Pnt("<<P1.X()<<","<<P1.Y()<<","<<P1.Z()<<")"<<endl;
+ gp_Pnt P2 = PP2.Pnt();
+ gp_Dir D1 = PP1.Tangent();
+ gp_Dir D2 = PP2.Tangent();
+ gp_Dir Dnew( gp_Vec( (D1.X()+D2.X())/2, (D1.Y()+D2.Y())/2,
+ (D1.Z()+D2.Z())/2 ) );
+ PP1.SetTangent(Dnew);
+ fullList.push_back(PP1);
+ itPP++;
+ for(; itPP!=currList.end(); itPP++) {
+ fullList.push_back( *itPP );
+ }
+ PP1 = fullList.back();
+ fullList.pop_back();
+ }
+ // if wire not closed
+ fullList.push_back(PP1);
+ // else ???
+ }
+ else {
+ return EXTR_BAD_PATH_SHAPE;
}
- // 2. Collect parameters on the track edge
- aPrms.push_back( aT1 );
- aPrms.push_back( aT2 );
+ return MakeExtrElements(theElements, fullList, theHasAngles, theAngles, theLinearVariation,
+ theHasRefPoint, theRefPoint, theMakeGroups);
+}
- aItN = pSubMeshDS->GetNodes();
- while ( aItN->more() ) {
- const SMDS_MeshNode* pNode = aItN->next();
- const SMDS_EdgePosition* pEPos =
- static_cast<const SMDS_EdgePosition*>( pNode->GetPosition().get() );
- aT = pEPos->GetUParameter();
- aPrms.push_back( aT );
- }
+//=======================================================================
+//function : MakeEdgePathPoints
+//purpose : auxilary for ExtrusionAlongTrack
+//=======================================================================
+SMESH_MeshEditor::Extrusion_Error
+SMESH_MeshEditor::MakeEdgePathPoints(std::list<double>& aPrms,
+ const TopoDS_Edge& aTrackEdge,
+ bool FirstIsStart,
+ list<SMESH_MeshEditor_PathPoint>& LPP)
+{
+ Standard_Real aTx1, aTx2, aL2, aTolVec, aTolVec2;
+ aTolVec=1.e-7;
+ aTolVec2=aTolVec*aTolVec;
+ double aT1, aT2;
+ TopoDS_Vertex aV1, aV2;
+ TopExp::Vertices( aTrackEdge, aV1, aV2 );
+ aT1=BRep_Tool::Parameter( aV1, aTrackEdge );
+ aT2=BRep_Tool::Parameter( aV2, aTrackEdge );
+ // 2. Collect parameters on the track edge
+ aPrms.push_front( aT1 );
+ aPrms.push_back( aT2 );
// sort parameters
aPrms.sort();
- if ( aN1 == theN1 ) {
+ if( FirstIsStart ) {
if ( aT1 > aT2 ) {
aPrms.reverse();
}
aPrms.reverse();
}
}
-
// 3. Path Points
SMESH_MeshEditor_PathPoint aPP;
- vector<SMESH_MeshEditor_PathPoint> aPPs( aNbTP );
- //
- aC3D = BRep_Tool::Curve( aTrackEdge, aTx1, aTx2 );
- //
- aItD = aPrms.begin();
- for ( j=0; aItD != aPrms.end(); ++aItD, ++j ) {
- aT = *aItD;
+ Handle(Geom_Curve) aC3D = BRep_Tool::Curve( aTrackEdge, aTx1, aTx2 );
+ std::list<double>::iterator aItD = aPrms.begin();
+ for(; aItD != aPrms.end(); ++aItD) {
+ double aT = *aItD;
+ gp_Pnt aP3D;
+ gp_Vec aVec;
aC3D->D1( aT, aP3D, aVec );
aL2 = aVec.SquareMagnitude();
if ( aL2 < aTolVec2 )
return EXTR_CANT_GET_TANGENT;
-
gp_Dir aTgt( aVec );
- aAngle = aAngles[j];
-
aPP.SetPnt( aP3D );
aPP.SetTangent( aTgt );
- aPP.SetAngle( aAngle );
aPP.SetParameter( aT );
- aPPs[j]=aPP;
+ LPP.push_back(aPP);
+ }
+ return EXTR_OK;
+}
+
+
+//=======================================================================
+//function : MakeExtrElements
+//purpose : auxilary for ExtrusionAlongTrack
+//=======================================================================
+SMESH_MeshEditor::Extrusion_Error
+SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet& theElements,
+ list<SMESH_MeshEditor_PathPoint>& fullList,
+ const bool theHasAngles,
+ list<double>& theAngles,
+ const bool theLinearVariation,
+ const bool theHasRefPoint,
+ const gp_Pnt& theRefPoint,
+ const bool theMakeGroups)
+{
+ //cout<<"MakeExtrElements fullList.size() = "<<fullList.size()<<endl;
+ int aNbTP = fullList.size();
+ vector<SMESH_MeshEditor_PathPoint> aPPs(aNbTP);
+ // Angles
+ if( theHasAngles && theAngles.size()>0 && theLinearVariation ) {
+ LinearAngleVariation(aNbTP-1, theAngles);
+ }
+ vector<double> aAngles( aNbTP );
+ int j = 0;
+ for(; j<aNbTP; ++j) {
+ aAngles[j] = 0.;
+ }
+ if ( theHasAngles ) {
+ double anAngle;;
+ std::list<double>::iterator aItD = theAngles.begin();
+ for ( j=1; (aItD != theAngles.end()) && (j<aNbTP); ++aItD, ++j ) {
+ anAngle = *aItD;
+ aAngles[j] = anAngle;
+ }
+ }
+ // fill vector of path points with angles
+ //aPPs.resize(fullList.size());
+ j = -1;
+ list<SMESH_MeshEditor_PathPoint>::iterator itPP = fullList.begin();
+ for(; itPP!=fullList.end(); itPP++) {
+ j++;
+ SMESH_MeshEditor_PathPoint PP = *itPP;
+ PP.SetAngle(aAngles[j]);
+ aPPs[j] = PP;
}
+ TNodeOfNodeListMap mapNewNodes;
+ TElemOfVecOfNnlmiMap mapElemNewNodes;
+ TElemOfElemListMap newElemsMap;
+ TIDSortedElemSet::iterator itElem;
+ double aX, aY, aZ;
+ int aNb;
+ SMDSAbs_ElementType aTypeE;
+ // source elements for each generated one
+ SMESH_SequenceOfElemPtr srcElems, srcNodes;
+
// 3. Center of rotation aV0
- aV0 = theRefPoint;
+ gp_Pnt aV0 = theRefPoint;
+ gp_XYZ aGC;
if ( !theHasRefPoint ) {
aNb = 0;
aGC.SetCoord( 0.,0.,0. );
-
+
itElem = theElements.begin();
for ( ; itElem != theElements.end(); itElem++ ) {
const SMDS_MeshElement* elem = *itElem;
-
+
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
while ( itN->more() ) {
const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( itN->next() );
aX = node->X();
aY = node->Y();
aZ = node->Z();
-
+
if ( mapNewNodes.find( node ) == mapNewNodes.end() ) {
list<const SMDS_MeshNode*> aLNx;
mapNewNodes[node] = aLNx;
const SMESH_MeshEditor_PathPoint& aPP0 = aPPs[0];
aP0x = aPP0.Pnt();
aDT0x= aPP0.Tangent();
+ //cout<<"j = 0 PP: Pnt("<<aP0x.X()<<","<<aP0x.Y()<<","<<aP0x.Z()<<")"<<endl;
for ( j = 1; j < aNbTP; ++j ) {
const SMESH_MeshEditor_PathPoint& aPP1 = aPPs[j];
return EXTR_OK;
}
+
+//=======================================================================
+//function : LinearAngleVariation
+//purpose : auxilary for ExtrusionAlongTrack
+//=======================================================================
+void SMESH_MeshEditor::LinearAngleVariation(const int nbSteps,
+ list<double>& Angles)
+{
+ int nbAngles = Angles.size();
+ if( nbSteps > nbAngles ) {
+ vector<double> theAngles(nbAngles);
+ list<double>::iterator it = Angles.begin();
+ int i = -1;
+ for(; it!=Angles.end(); it++) {
+ i++;
+ theAngles[i] = (*it);
+ }
+ list<double> res;
+ double rAn2St = double( nbAngles ) / double( nbSteps );
+ double angPrev = 0, angle;
+ for ( int iSt = 0; iSt < nbSteps; ++iSt ) {
+ double angCur = rAn2St * ( iSt+1 );
+ double angCurFloor = floor( angCur );
+ double angPrevFloor = floor( angPrev );
+ if ( angPrevFloor == angCurFloor )
+ angle = rAn2St * theAngles[ int( angCurFloor ) ];
+ else {
+ int iP = int( angPrevFloor );
+ double angPrevCeil = ceil(angPrev);
+ angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
+
+ int iC = int( angCurFloor );
+ if ( iC < nbAngles )
+ angle += ( angCur - angCurFloor ) * theAngles[ iC ];
+
+ iP = int( angPrevCeil );
+ while ( iC-- > iP )
+ angle += theAngles[ iC ];
+ }
+ res.push_back(angle);
+ angPrev = angCur;
+ }
+ Angles.clear();
+ it = res.begin();
+ for(; it!=res.end(); it++)
+ Angles.push_back( *it );
+ }
+}
+
+
//=======================================================================
//function : Transform
//purpose :
SMDS_MeshNode tgtNode( thePnt.X(), thePnt.Y(), thePnt.Z() );
list<const SMDS_MeshNode*> nodes;
const double precision = 1e-6;
- myOctreeNode->NodesAround( &tgtNode, &nodes, precision );
+ //myOctreeNode->NodesAround( &tgtNode, &nodes, precision );
double minSqDist = DBL_MAX;
Bnd_B3d box;
TNodeNodeMap::iterator nnIt = nodeNodeMap.find( n );
if ( nnIt != nodeNodeMap.end() ) { // n sticks
n = (*nnIt).second;
+ // BUG 0020185: begin
+ {
+ bool stopRecur = false;
+ set<const SMDS_MeshNode*> nodesRecur;
+ nodesRecur.insert(n);
+ while (!stopRecur) {
+ TNodeNodeMap::iterator nnIt_i = nodeNodeMap.find( n );
+ if ( nnIt_i != nodeNodeMap.end() ) { // n sticks
+ n = (*nnIt_i).second;
+ if (!nodesRecur.insert(n).second) {
+ // error: recursive dependancy
+ stopRecur = true;
+ }
+ }
+ else
+ stopRecur = true;
+ }
+ }
+ // BUG 0020185: end
iRepl[ nbRepl++ ] = iCur;
}
curNodes[ iCur ] = n;
//=======================================================================
int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm,
- SMESH_MesherHelper& theHelper,
- const bool theForce3d)
+ SMESH_MesherHelper& theHelper,
+ const bool theForce3d)
{
int nbElem = 0;
if( !theSm ) return nbElem;
+
+ const bool notFromGroups = false;
SMDS_ElemIteratorPtr ElemItr = theSm->GetElements();
while(ElemItr->more())
{
}
SMDSAbs_ElementType aType = elem->GetType();
- theSm->RemoveElement(elem);
- GetMeshDS()->SMDS_Mesh::RemoveFreeElement(elem);
+ GetMeshDS()->RemoveFreeElement(elem, theSm, notFromGroups);
const SMDS_MeshElement* NewElem = 0;
switch(nbNodes)
{
case 4:
- NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], id, true);
+ NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d);
break;
case 6:
- NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], aNds[4], aNds[5], id, true);
+ NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], aNds[4], aNds[5], id, theForce3d);
break;
case 8:
NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3],
- aNds[4], aNds[5], aNds[6], aNds[7], id, true);
+ aNds[4], aNds[5], aNds[6], aNds[7], id, theForce3d);
break;
default:
continue;
default :
continue;
}
+ ReplaceElemInGroups( elem, NewElem, GetMeshDS());
if( NewElem )
- {
- AddToSameGroups( NewElem, elem, GetMeshDS());
theSm->AddElement( NewElem );
- }
- if ( NewElem != elem )
- RemoveElemFromGroups (elem, GetMeshDS());
}
return nbElem;
}
SMESH_MesherHelper aHelper(*myMesh);
aHelper.SetIsQuadratic( true );
+ const bool notFromGroups = false;
int nbCheckedElems = 0;
if ( myMesh->HasShapeToMesh() )
SMESH_subMesh* sm = smIt->next();
if ( SMESHDS_SubMesh *smDS = sm->GetSubMeshDS() ) {
aHelper.SetSubShape( sm->GetSubShape() );
+ if ( !theForce3d) aHelper.SetCheckNodePosition(true);
nbCheckedElems += convertElemToQuadratic(smDS, aHelper, theForce3d);
}
}
}
}
int totalNbElems = meshDS->NbEdges() + meshDS->NbFaces() + meshDS->NbVolumes();
- if ( nbCheckedElems < totalNbElems ) // not all elements in submeshes
+ if ( nbCheckedElems < totalNbElems ) // not all elements are in submeshes
{
+ SMESHDS_SubMesh *smDS = 0;
SMDS_EdgeIteratorPtr aEdgeItr = meshDS->edgesIterator();
while(aEdgeItr->more())
{
const SMDS_MeshNode* n1 = edge->GetNode(0);
const SMDS_MeshNode* n2 = edge->GetNode(1);
- meshDS->SMDS_Mesh::RemoveFreeElement(edge);
+ meshDS->RemoveFreeElement(edge, smDS, notFromGroups);
const SMDS_MeshEdge* NewEdge = aHelper.AddEdge(n1, n2, id, theForce3d);
- if ( NewEdge )
- AddToSameGroups(NewEdge, edge, meshDS);
- if ( NewEdge != edge )
- RemoveElemFromGroups (edge, meshDS);
+ ReplaceElemInGroups( edge, NewEdge, GetMeshDS());
}
}
SMDS_FaceIteratorPtr aFaceItr = meshDS->facesIterator();
aNds[i] = face->GetNode(i);
}
- meshDS->SMDS_Mesh::RemoveFreeElement(face);
+ meshDS->RemoveFreeElement(face, smDS, notFromGroups);
SMDS_MeshFace * NewFace = 0;
switch(nbNodes)
default:
continue;
}
- if ( NewFace )
- AddToSameGroups(NewFace, face, meshDS);
- if ( NewFace != face )
- RemoveElemFromGroups (face, meshDS);
+ ReplaceElemInGroups( face, NewFace, GetMeshDS());
}
SMDS_VolumeIteratorPtr aVolumeItr = meshDS->volumesIterator();
while(aVolumeItr->more())
aNds[i] = volume->GetNode(i);
}
- meshDS->SMDS_Mesh::RemoveFreeElement(volume);
+ meshDS->RemoveFreeElement(volume, smDS, notFromGroups);
SMDS_MeshVolume * NewVolume = 0;
switch(nbNodes)
{
case 4:
NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2],
- aNds[3], id, true );
+ aNds[3], id, theForce3d );
break;
case 6:
NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2],
- aNds[3], aNds[4], aNds[5], id, true);
+ aNds[3], aNds[4], aNds[5], id, theForce3d);
break;
case 8:
NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3],
- aNds[4], aNds[5], aNds[6], aNds[7], id, true);
+ aNds[4], aNds[5], aNds[6], aNds[7], id, theForce3d);
break;
default:
continue;
}
- if ( NewVolume )
- AddToSameGroups(NewVolume, volume, meshDS);
- if ( NewVolume != volume )
- RemoveElemFromGroups (volume, meshDS);
+ ReplaceElemInGroups(volume, NewVolume, meshDS);
}
}
+ if ( !theForce3d ) {
+ aHelper.SetSubShape(0); // apply to the whole mesh
+ aHelper.FixQuadraticElements();
+ }
}
//=======================================================================
{
int nbElem = 0;
SMESHDS_Mesh* meshDS = GetMeshDS();
+ const bool notFromGroups = false;
+
while( theItr->more() )
{
const SMDS_MeshElement* elem = theItr->next();
SMDSAbs_ElementType aType = elem->GetType();
//remove old quadratic element
- meshDS->SMDS_Mesh::RemoveFreeElement( elem );
- if ( theSm )
- theSm->RemoveElement( elem );
+ meshDS->RemoveFreeElement( elem, theSm, notFromGroups );
SMDS_MeshElement * NewElem = AddElement( aNds, aType, false, id );
- if ( NewElem )
- AddToSameGroups(NewElem, elem, meshDS);
- if ( NewElem != elem )
- RemoveElemFromGroups (elem, meshDS);
+ ReplaceElemInGroups(elem, NewElem, meshDS);
if( theSm && NewElem )
theSm->AddElement( NewElem );
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() ));
int totalNbElems =
GetMeshDS()->NbEdges() + GetMeshDS()->NbFaces() + GetMeshDS()->NbVolumes();
- if ( nbCheckedElems < totalNbElems ) // not all elements in submeshes
+ if ( nbCheckedElems < totalNbElems ) // not all elements are in submeshes
{
SMESHDS_SubMesh *aSM = 0;
removeQuadElem( aSM, GetMeshDS()->elementsIterator(), 0 );
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 theElems - the list of elements (edges or faces) to be replicated
+ The nodes for duplication could be found from these elements
+ \param theNodesNot - list of nodes to NOT replicate
+ \param theAffectedElems - the list of elements (cells and edges) to which the
+ replicated nodes should be associated to.
+ \return TRUE if operation has been completed successfully, FALSE otherwise
+*/
+bool SMESH_MeshEditor::DoubleNodes( const TIDSortedElemSet& theElems,
+ const TIDSortedElemSet& theNodesNot,
+ const TIDSortedElemSet& theAffectedElems )
+{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
+ if ( theElems.size() == 0 )
+ return false;
+
+ SMESHDS_Mesh* aMeshDS = GetMeshDS();
+ if ( !aMeshDS )
+ return false;
+
+ bool res = false;
+ std::map< const SMDS_MeshNode*, const SMDS_MeshNode* > anOldNodeToNewNode;
+ // duplicate elements and nodes
+ res = doubleNodes( aMeshDS, theElems, theNodesNot, anOldNodeToNewNode, true );
+ // replce nodes by duplications
+ res = doubleNodes( aMeshDS, theAffectedElems, theNodesNot, anOldNodeToNewNode, false );
+ return res;
+}
+
+/*!
+ \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+ \param theMeshDS - mesh instance
+ \param theElems - the elements replicated or modified (nodes should be changed)
+ \param theNodesNot - nodes to NOT replicate
+ \param theNodeNodeMap - relation of old node to new created node
+ \param theIsDoubleElem - flag os to replicate element or modify
+ \return TRUE if operation has been completed successfully, FALSE otherwise
+*/
+bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh* theMeshDS,
+ const TIDSortedElemSet& theElems,
+ const TIDSortedElemSet& theNodesNot,
+ std::map< const SMDS_MeshNode*,
+ const SMDS_MeshNode* >& theNodeNodeMap,
+ const bool theIsDoubleElem )
+{
+ // iterate on through element and duplicate them (by nodes duplication)
+ bool res = false;
+ TIDSortedElemSet::iterator elemItr = theElems.begin();
+ for ( ; elemItr != theElems.end(); ++elemItr )
+ {
+ const SMDS_MeshElement* anElem = *elemItr;
+ if (!anElem)
+ continue;
+
+ bool isDuplicate = false;
+ // duplicate nodes to duplicate element
+ std::vector<const SMDS_MeshNode*> newNodes( anElem->NbNodes() );
+ SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
+ int ind = 0;
+ while ( anIter->more() )
+ {
+
+ SMDS_MeshNode* aCurrNode = (SMDS_MeshNode*)anIter->next();
+ SMDS_MeshNode* aNewNode = aCurrNode;
+ if ( theNodeNodeMap.find( aCurrNode ) != theNodeNodeMap.end() )
+ aNewNode = (SMDS_MeshNode*)theNodeNodeMap[ aCurrNode ];
+ else if ( theIsDoubleElem && theNodesNot.find( aCurrNode ) == theNodesNot.end() )
+ {
+ // duplicate node
+ aNewNode = theMeshDS->AddNode( aCurrNode->X(), aCurrNode->Y(), aCurrNode->Z() );
+ theNodeNodeMap[ aCurrNode ] = aNewNode;
+ myLastCreatedNodes.Append( aNewNode );
+ }
+ isDuplicate |= (aCurrNode == aNewNode);
+ newNodes[ ind++ ] = aNewNode;
+ }
+ if ( !isDuplicate )
+ continue;
+
+ if ( theIsDoubleElem )
+ myLastCreatedElems.Append( AddElement(newNodes, anElem->GetType(), anElem->IsPoly()) );
+ else
+ theMeshDS->ChangeElementNodes( anElem, &newNodes[ 0 ], anElem->NbNodes() );
+
+ res = true;
+ }
+ return res;
+}
+
+/*!
+ \brief Check if element located inside shape
+ \return TRUE if IN or ON shape, FALSE otherwise
+*/
+
+static bool isInside(const SMDS_MeshElement* theElem,
+ BRepClass3d_SolidClassifier& theBsc3d,
+ const double theTol)
+{
+ gp_XYZ centerXYZ (0, 0, 0);
+ SMDS_ElemIteratorPtr aNodeItr = theElem->nodesIterator();
+ while (aNodeItr->more())
+ {
+ SMDS_MeshNode* aNode = (SMDS_MeshNode*)aNodeItr->next();
+ centerXYZ += gp_XYZ(aNode->X(), aNode->Y(), aNode->Z());
+ }
+ gp_Pnt aPnt(centerXYZ);
+ theBsc3d.Perform(aPnt, theTol);
+ TopAbs_State aState = theBsc3d.State();
+ return (aState == TopAbs_IN || aState == TopAbs_ON );
+}
+
+/*!
+ \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+ \param theElems - group of of elements (edges or faces) to be replicated
+ \param theNodesNot - group of nodes not to replicated
+ \param theShape - shape to detect affected elements (element which geometric center
+ located on or inside shape).
+ The replicated nodes should be associated to affected elements.
+ \return TRUE if operation has been completed successfully, FALSE otherwise
+*/
+
+bool SMESH_MeshEditor::DoubleNodesInRegion( const TIDSortedElemSet& theElems,
+ const TIDSortedElemSet& theNodesNot,
+ const TopoDS_Shape& theShape )
+{
+ SMESHDS_Mesh* aMesh = GetMeshDS();
+ if (!aMesh)
+ return false;
+ if ( theShape.IsNull() )
+ return false;
+
+ const double aTol = Precision::Confusion();
+ BRepClass3d_SolidClassifier bsc3d(theShape);
+ bsc3d.PerformInfinitePoint(aTol);
+
+ // iterates on indicated elements and get elements by back references from their nodes
+ TIDSortedElemSet anAffected;
+ TIDSortedElemSet::iterator elemItr = theElems.begin();
+ for ( ; elemItr != theElems.end(); ++elemItr )
+ {
+ SMDS_MeshElement* anElem = (SMDS_MeshElement*)*elemItr;
+ if (!anElem)
+ continue;
+
+ SMDS_ElemIteratorPtr nodeItr = anElem->nodesIterator();
+ while ( nodeItr->more() )
+ {
+ const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(nodeItr->next());
+ if ( !aNode || theNodesNot.find(aNode) != theNodesNot.end() )
+ continue;
+ SMDS_ElemIteratorPtr backElemItr = aNode->GetInverseElementIterator();
+ while ( backElemItr->more() )
+ {
+ SMDS_MeshElement* curElem = (SMDS_MeshElement*)backElemItr->next();
+ if ( curElem && theElems.find(curElem) == theElems.end() &&
+ isInside( curElem, bsc3d, aTol ) )
+ anAffected.insert( curElem );
+ }
+ }
+ }
+ return DoubleNodes( theElems, theNodesNot, anAffected );
+}