Back to index

salome-smesh  6.5.0
SMESH_MeshEditor_i.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 //  File   : SMESH_MeshEditor_i.cxx
00023 //  Author : Nicolas REJNERI
00024 //  Module : SMESH
00025 
00026 #ifdef WNT
00027 #define NOMINMAX
00028 #endif
00029 
00030 #include "SMESH_MeshEditor_i.hxx"
00031 
00032 #include "SMDS_LinearEdge.hxx"
00033 #include "SMDS_Mesh0DElement.hxx"
00034 #include "SMDS_MeshFace.hxx"
00035 #include "SMDS_MeshVolume.hxx"
00036 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
00037 #include "SMDS_SetIterator.hxx"
00038 #include "SMESHDS_Group.hxx"
00039 #include "SMESH_ControlsDef.hxx"
00040 #include "SMESH_Filter_i.hxx"
00041 #include "SMESH_Gen_i.hxx"
00042 #include "SMESH_Group_i.hxx"
00043 #include "SMESH_PythonDump.hxx"
00044 #include "SMESH_subMeshEventListener.hxx"
00045 #include "SMESH_subMesh_i.hxx"
00046 
00047 #include "utilities.h"
00048 #include "Utils_ExceptHandlers.hxx"
00049 #include "Utils_CorbaException.hxx"
00050 
00051 #include <BRepAdaptor_Surface.hxx>
00052 #include <BRep_Tool.hxx>
00053 #include <TopExp_Explorer.hxx>
00054 #include <TopoDS.hxx>
00055 #include <TopoDS_Edge.hxx>
00056 #include <TopoDS_Face.hxx>
00057 #include <gp_Ax1.hxx>
00058 #include <gp_Ax2.hxx>
00059 #include <gp_Vec.hxx>
00060 
00061 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
00062 #define NO_CAS_CATCH
00063 #endif
00064 
00065 #include <Standard_Failure.hxx>
00066 
00067 #ifdef NO_CAS_CATCH
00068 #include <Standard_ErrorHandler.hxx>
00069 #endif
00070 
00071 #include <sstream>
00072 #include <limits>
00073 
00074 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
00075 
00076 using namespace std;
00077 using SMESH::TPythonDump;
00078 using SMESH::TVar;
00079 
00080 namespace {
00081 
00082   //=============================================================================
00086   //=============================================================================
00087 
00088   struct TPreviewMesh: public SMESH_Mesh
00089   {
00090     SMDSAbs_ElementType myPreviewType; // type to show
00092     TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
00093       _isShapeToMesh = (_id =_studyId =_idDoc = 0);
00094       _myMeshDS  = new SMESHDS_Mesh( _id, true );
00095       myPreviewType = previewElements;
00096     }
00098     virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
00100     void Copy(const TIDSortedElemSet & theElements,
00101               TIDSortedElemSet&        theCopyElements,
00102               SMDSAbs_ElementType      theSelectType = SMDSAbs_All,
00103               SMDSAbs_ElementType      theAvoidType = SMDSAbs_All)
00104     {
00105       // loop on theIDsOfElements
00106       TIDSortedElemSet::const_iterator eIt = theElements.begin();
00107       for ( ; eIt != theElements.end(); ++eIt )
00108       {
00109         const SMDS_MeshElement* anElem = *eIt;
00110         if ( !anElem ) continue;
00111         SMDSAbs_ElementType type = anElem->GetType();
00112         if ( type == theAvoidType ||
00113              ( theSelectType != SMDSAbs_All && type != theSelectType ))
00114           continue;
00115         const SMDS_MeshElement* anElemCopy;
00116         if ( type == SMDSAbs_Node)
00117           anElemCopy = Copy( cast2Node(anElem) );
00118         else
00119           anElemCopy = Copy( anElem );
00120         if ( anElemCopy )
00121           theCopyElements.insert( theCopyElements.end(), anElemCopy );
00122       }
00123     }
00125     SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
00126     {
00127       // copy element nodes
00128       int anElemNbNodes = anElem->NbNodes();
00129       vector< int > anElemNodesID( anElemNbNodes ) ;
00130       SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
00131       for ( int i = 0; itElemNodes->more(); i++)
00132       {
00133         const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
00134         Copy( anElemNode );
00135         anElemNodesID[i] = anElemNode->GetID();
00136       }
00137 
00138       // creates a corresponding element on copied nodes
00139       SMDS_MeshElement* anElemCopy = 0;
00140       if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
00141       {
00142         const SMDS_VtkVolume* ph =
00143           dynamic_cast<const SMDS_VtkVolume*> (anElem);
00144         if ( ph )
00145           anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
00146             (anElemNodesID, ph->GetQuantities(),anElem->GetID());
00147       }
00148       else {
00149         anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
00150                                                           anElem->GetType(),
00151                                                           anElem->IsPoly() );
00152       }
00153       return anElemCopy;
00154     }
00156     SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
00157     {
00158       return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
00159                                       anElemNode->GetID());
00160     }
00161   };// struct TPreviewMesh
00162 
00163   static SMESH_NodeSearcher *    theNodeSearcher    = 0;
00164   static SMESH_ElementSearcher * theElementSearcher = 0;
00165 
00166   //=============================================================================
00170   //=============================================================================
00171 
00172   struct TSearchersDeleter : public SMESH_subMeshEventListener
00173   {
00174     SMESH_Mesh* myMesh;
00175     string      myMeshPartIOR;
00177     TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
00178                                                      "SMESH_MeshEditor_i::TSearchersDeleter"),
00179                          myMesh(0) {}
00181     static void Delete()
00182     {
00183       if ( theNodeSearcher )    delete theNodeSearcher;    theNodeSearcher    = 0;
00184       if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
00185     }
00186     typedef map < int, SMESH_subMesh * > TDependsOnMap;
00188     void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
00189                       SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
00190     {
00191       if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
00192         Delete();
00193         Unset( sm->GetFather() );
00194       }
00195     }
00197     void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
00198     {
00199       if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
00200       {
00201         if ( myMesh ) {
00202           Delete();
00203           Unset( myMesh );
00204         }
00205         myMesh = mesh;
00206         myMeshPartIOR = meshPartIOR;
00207         if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
00208           const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
00209           TDependsOnMap::const_iterator sm;
00210           for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
00211             sm->second->SetEventListener( this, 0, sm->second );
00212         }
00213       }
00214     }
00216     void Unset(SMESH_Mesh* mesh)
00217     {
00218       if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
00219         const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
00220         TDependsOnMap::const_iterator sm;
00221         for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
00222           sm->second->DeleteEventListener( this );
00223       }
00224       myMesh = 0;
00225     }
00226 
00227   } theSearchersDeleter;
00228 
00229   TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
00230   {
00231     TCollection_AsciiString typeStr;
00232     switch ( theMirrorType ) {
00233     case  SMESH::SMESH_MeshEditor::POINT:
00234       typeStr = "SMESH.SMESH_MeshEditor.POINT";
00235       break;
00236     case  SMESH::SMESH_MeshEditor::AXIS:
00237       typeStr = "SMESH.SMESH_MeshEditor.AXIS";
00238       break;
00239     default:
00240       typeStr = "SMESH.SMESH_MeshEditor.PLANE";
00241     }
00242     return typeStr;
00243   }
00244   //================================================================================
00252   //================================================================================
00253 
00254   void arrayToSet(const SMESH::long_array & IDs,
00255                   const SMESHDS_Mesh*       aMesh,
00256                   TIDSortedElemSet&         aMap,
00257                   const SMDSAbs_ElementType aType = SMDSAbs_All )
00258   {
00259     for (int i=0; i<IDs.length(); i++) {
00260       CORBA::Long ind = IDs[i];
00261       const SMDS_MeshElement * elem =
00262         (aType == SMDSAbs_Node ? aMesh->FindNode(ind) : aMesh->FindElement(ind));
00263       if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
00264         aMap.insert( elem );
00265     }
00266   }
00267   //================================================================================
00271   //================================================================================
00272 
00273   bool idSourceToSet(SMESH::SMESH_IDSource_ptr  theIDSource,
00274                      const SMESHDS_Mesh*        theMeshDS,
00275                      TIDSortedElemSet&          theElemSet,
00276                      const SMDSAbs_ElementType  theType,
00277                      const bool                 emptyIfIsMesh=false)
00278 
00279   {
00280     if ( CORBA::is_nil( theIDSource ) )
00281       return false;
00282     if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
00283       return true;
00284 
00285     SMESH::long_array_var anIDs = theIDSource->GetIDs();
00286     if ( anIDs->length() == 0 )
00287       return false;
00288     SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
00289     if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
00290     {
00291       if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
00292         arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
00293       else
00294         return false;
00295     }
00296     else
00297     {
00298       arrayToSet( anIDs, theMeshDS, theElemSet, theType);
00299     }
00300     return true;
00301   }
00302   //================================================================================
00306   //================================================================================
00307 
00308   void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr  theObject,
00309                          const SMESHDS_Mesh*        theMeshDS,
00310                          TIDSortedNodeSet&          theNodeSet)
00311 
00312   {
00313     if ( CORBA::is_nil( theObject ) )
00314       return;
00315     SMESH::array_of_ElementType_var types = theObject->GetTypes();
00316     SMESH::long_array_var     aElementsId = theObject->GetIDs();
00317     if ( types->length() == 1 && types[0] == SMESH::NODE)
00318     {
00319       for(int i = 0; i < aElementsId->length(); i++)
00320         if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
00321           theNodeSet.insert( theNodeSet.end(), n);
00322     }
00323     else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
00324     {
00325       SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
00326       while ( nIt->more( ))
00327         if( const SMDS_MeshElement * elem = nIt->next() )
00328           theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
00329     }
00330     else
00331     {
00332       for(int i = 0; i < aElementsId->length(); i++)
00333         if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
00334           theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
00335     }
00336   }
00337 
00338   //================================================================================
00342   //================================================================================
00343 
00344   void getElementsAround(const TIDSortedElemSet& theElements,
00345                          const SMESHDS_Mesh*     theMeshDS,
00346                          TIDSortedElemSet&       theElementsAround)
00347   {
00348     if ( theElements.empty() ) return;
00349 
00350     SMDSAbs_ElementType elemType    = (*theElements.begin())->GetType();
00351     bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
00352     if ( sameElemType &&
00353          theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
00354       return; // all the elements are in theElements
00355 
00356     if ( !sameElemType )
00357       elemType = SMDSAbs_All;
00358 
00359     TIDSortedElemSet visitedNodes;
00360     TIDSortedElemSet::const_iterator elemIt = theElements.begin();
00361     for ( ; elemIt != theElements.end(); ++elemIt )
00362     {
00363       const SMDS_MeshElement* e = *elemIt;
00364       int i = e->NbCornerNodes();
00365       while ( --i != -1 )
00366       {
00367         const SMDS_MeshNode* n = e->GetNode( i );
00368         if ( visitedNodes.insert( n ).second )
00369         {
00370           SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
00371           while ( invIt->more() )
00372           {
00373             const SMDS_MeshElement* elemAround = invIt->next();
00374             if ( !theElements.count( elemAround ))
00375               theElementsAround.insert( elemAround );
00376           }
00377         }
00378       }
00379     }
00380   }
00381 }
00382 
00383 //=============================================================================
00387 //=============================================================================
00388 
00389 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview)
00390 {
00391   myMesh_i = theMesh;
00392   myMesh = & theMesh->GetImpl();
00393   myPreviewMode = isPreview;
00394 }
00395 
00396 //================================================================================
00400 //================================================================================
00401 
00402 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
00403 {
00404 }
00405 
00406 //================================================================================
00410 //================================================================================
00411 
00412 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
00413 {
00414   if ( myPreviewMode ) {
00415     myPreviewData = new SMESH::MeshPreviewStruct();
00416   }
00417   else {
00418     myLastCreatedElems = new SMESH::long_array();
00419     myLastCreatedNodes = new SMESH::long_array();
00420     if ( deleteSearchers )
00421       TSearchersDeleter::Delete();
00422   }
00423 }
00424 
00425 //=======================================================================
00426 //function : MakeIDSource
00427 //purpose  : Wrap a sequence of ids in a SMESH_IDSource
00428 //=======================================================================
00429 
00430 struct _IDSource : public POA_SMESH::SMESH_IDSource
00431 {
00432   SMESH::long_array     _ids;
00433   SMESH::ElementType    _type;
00434   SMESH::SMESH_Mesh_ptr _mesh;
00435   SMESH::long_array* GetIDs()      { return new SMESH::long_array( _ids ); }
00436   SMESH::long_array* GetMeshInfo() { return 0; }
00437   SMESH::SMESH_Mesh_ptr GetMesh()  { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
00438   bool IsMeshInfoCorrect()         { return true; }
00439   SMESH::array_of_ElementType* GetTypes()
00440   {
00441     SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
00442     if ( _ids.length() > 0 ) {
00443       types->length( 1 );
00444       types[0] = _type;
00445     }
00446     return types._retn();
00447   }
00448 };
00449 
00450 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
00451                                                            SMESH::ElementType       type)
00452 {
00453   _IDSource* anIDSource = new _IDSource;
00454   anIDSource->_ids = ids;
00455   anIDSource->_type = type;
00456   anIDSource->_mesh = myMesh_i->_this();
00457   SMESH::SMESH_IDSource_var anIDSourceVar = anIDSource->_this();
00458 
00459   return anIDSourceVar._retn();
00460 }
00461 
00462 //=============================================================================
00466 //=============================================================================
00467 
00468 CORBA::Boolean
00469 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
00470 {
00471   initData();
00472 
00473   ::SMESH_MeshEditor anEditor( myMesh );
00474   list< int > IdList;
00475 
00476   for (int i = 0; i < IDsOfElements.length(); i++)
00477     IdList.push_back( IDsOfElements[i] );
00478 
00479   // Update Python script
00480   TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
00481 
00482   // Remove Elements
00483   bool ret = anEditor.Remove( IdList, false );
00484   myMesh->GetMeshDS()->Modified();
00485   if ( IDsOfElements.length() )
00486     myMesh->SetIsModified( true ); // issue 0020693
00487   return ret;
00488 }
00489 
00490 //=============================================================================
00494 //=============================================================================
00495 
00496 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
00497 {
00498   initData();
00499 
00500   ::SMESH_MeshEditor anEditor( myMesh );
00501   list< int > IdList;
00502   for (int i = 0; i < IDsOfNodes.length(); i++)
00503     IdList.push_back( IDsOfNodes[i] );
00504 
00505   // Update Python script
00506   TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
00507 
00508   bool ret = anEditor.Remove( IdList, true );
00509   myMesh->GetMeshDS()->Modified();
00510   if ( IDsOfNodes.length() )
00511     myMesh->SetIsModified( true ); // issue 0020693
00512   return ret;
00513 }
00514 
00515 //=============================================================================
00519 //=============================================================================
00520 
00521 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
00522 {
00523   initData();
00524 
00525   ::SMESH_MeshEditor anEditor( myMesh );
00526 
00527   // Update Python script
00528   TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
00529 
00530   // Create filter to find all orphan nodes
00531   SMESH::Controls::Filter::TIdSequence seq;
00532   SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
00533   SMESH::Controls::Filter::GetElementsId( GetMeshDS(), predicate, seq );
00534 
00535   // remove orphan nodes (if there are any)
00536   list< int > IdList;
00537   for ( int i = 0; i < seq.size(); i++ )
00538     IdList.push_back( seq[i] );
00539 
00540   int nbNodesBefore = myMesh->NbNodes();
00541   anEditor.Remove( IdList, true );
00542   myMesh->GetMeshDS()->Modified();
00543   if ( IdList.size() )
00544     myMesh->SetIsModified( true );
00545   int nbNodesAfter = myMesh->NbNodes();
00546 
00547   return nbNodesBefore - nbNodesAfter;
00548 }
00549 
00550 //=============================================================================
00554 //=============================================================================
00555 
00556 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
00557                                         CORBA::Double y, CORBA::Double z)
00558 {
00559   initData();
00560 
00561   const SMDS_MeshNode* N = GetMeshDS()->AddNode(x, y, z);
00562 
00563   // Update Python script
00564   TPythonDump() << "nodeID = " << this << ".AddNode( "
00565                 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
00566 
00567   myMesh->GetMeshDS()->Modified();
00568   myMesh->SetIsModified( true ); // issue 0020693
00569   return N->GetID();
00570 }
00571 
00572 //=============================================================================
00576 //=============================================================================
00577 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
00578 {
00579   initData();
00580 
00581   const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDOfNode);
00582   SMDS_MeshElement* elem = GetMeshDS()->Add0DElement(aNode);
00583 
00584   // Update Python script
00585   TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
00586 
00587   myMesh->GetMeshDS()->Modified();
00588   myMesh->SetIsModified( true ); // issue 0020693
00589 
00590   if (elem)
00591     return elem->GetID();
00592 
00593   return 0;
00594 }
00595 
00596 //=============================================================================
00600 //=============================================================================
00601 
00602 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
00603 {
00604   initData();
00605 
00606   int NbNodes = IDsOfNodes.length();
00607   SMDS_MeshElement* elem = 0;
00608   if (NbNodes == 2)
00609   {
00610     CORBA::Long index1 = IDsOfNodes[0];
00611     CORBA::Long index2 = IDsOfNodes[1];
00612     elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2));
00613 
00614     // Update Python script
00615     TPythonDump() << "edge = " << this << ".AddEdge([ "
00616                   << index1 << ", " << index2 <<" ])";
00617   }
00618   if (NbNodes == 3) {
00619     CORBA::Long n1 = IDsOfNodes[0];
00620     CORBA::Long n2 = IDsOfNodes[1];
00621     CORBA::Long n12 = IDsOfNodes[2];
00622     elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1),
00623                                 GetMeshDS()->FindNode(n2),
00624                                 GetMeshDS()->FindNode(n12));
00625     // Update Python script
00626     TPythonDump() << "edgeID = " << this << ".AddEdge([ "
00627                   <<n1<<", "<<n2<<", "<<n12<<" ])";
00628   }
00629 
00630   myMesh->GetMeshDS()->Modified();
00631   if(elem)
00632     return myMesh->SetIsModified( true ), elem->GetID();
00633 
00634   return 0;
00635 }
00636 
00637 //=============================================================================
00641 //=============================================================================
00642 
00643 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
00644 {
00645   initData();
00646 
00647   int NbNodes = IDsOfNodes.length();
00648   if (NbNodes < 3)
00649   {
00650     return 0;
00651   }
00652 
00653   std::vector<const SMDS_MeshNode*> nodes (NbNodes);
00654   for (int i = 0; i < NbNodes; i++)
00655     nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
00656 
00657   SMDS_MeshElement* elem = 0;
00658   if (NbNodes == 3) {
00659     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
00660   }
00661   else if (NbNodes == 4) {
00662     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
00663   }
00664   else if (NbNodes == 6) {
00665     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
00666                                 nodes[4], nodes[5]);
00667   }
00668   else if (NbNodes == 8) {
00669     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
00670                                 nodes[4], nodes[5], nodes[6], nodes[7]);
00671   }
00672   else if (NbNodes == 9) {
00673     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
00674                                 nodes[4], nodes[5], nodes[6], nodes[7], nodes[8] );
00675   }
00676   else if (NbNodes > 2) {
00677     elem = GetMeshDS()->AddPolygonalFace(nodes);
00678   }
00679 
00680   // Update Python script
00681   TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
00682 
00683   myMesh->GetMeshDS()->Modified();
00684   if(elem)
00685     return myMesh->SetIsModified( true ), elem->GetID();
00686 
00687   return 0;
00688 }
00689 
00690 //=============================================================================
00694 //=============================================================================
00695 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
00696 {
00697   initData();
00698 
00699   int NbNodes = IDsOfNodes.length();
00700   std::vector<const SMDS_MeshNode*> nodes (NbNodes);
00701   for (int i = 0; i < NbNodes; i++)
00702     nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
00703 
00704   const SMDS_MeshElement* elem = GetMeshDS()->AddPolygonalFace(nodes);
00705 
00706   // Update Python script
00707   TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
00708 
00709   myMesh->GetMeshDS()->Modified();
00710   return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
00711 }
00712 
00713 //=============================================================================
00717 //=============================================================================
00718 
00719 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
00720 {
00721   initData();
00722 
00723   int NbNodes = IDsOfNodes.length();
00724   vector< const SMDS_MeshNode*> n(NbNodes);
00725   for(int i=0;i<NbNodes;i++)
00726     n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
00727 
00728   SMDS_MeshElement* elem = 0;
00729   switch(NbNodes)
00730   {
00731   case 4 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
00732   case 5 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
00733   case 6 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
00734   case 8 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
00735   case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
00736                                         n[6],n[7],n[8],n[9]);
00737     break;
00738   case 12:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
00739                                         n[6],n[7],n[8],n[9],n[10],n[11]);
00740     break;
00741   case 13:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
00742                                         n[7],n[8],n[9],n[10],n[11],n[12]);
00743     break;
00744   case 15:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
00745                                         n[9],n[10],n[11],n[12],n[13],n[14]);
00746     break;
00747   case 20:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
00748                                         n[8],n[9],n[10],n[11],n[12],n[13],n[14],
00749                                         n[15],n[16],n[17],n[18],n[19]);
00750     break;
00751   case 27:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
00752                                         n[8],n[9],n[10],n[11],n[12],n[13],n[14],
00753                                         n[15],n[16],n[17],n[18],n[19],
00754                                         n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
00755     break;
00756   }
00757 
00758   // Update Python script
00759   TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
00760 
00761   myMesh->GetMeshDS()->Modified();
00762   if(elem)
00763     return myMesh->SetIsModified( true ), elem->GetID();
00764 
00765   return 0;
00766 }
00767 
00768 //=============================================================================
00772 //=============================================================================
00773 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
00774                                                      const SMESH::long_array & Quantities)
00775 {
00776   initData();
00777 
00778   int NbNodes = IDsOfNodes.length();
00779   std::vector<const SMDS_MeshNode*> n (NbNodes);
00780   for (int i = 0; i < NbNodes; i++)
00781     {
00782       const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDsOfNodes[i]);
00783       if (!aNode) return 0;
00784       n[i] = aNode;
00785     }
00786 
00787   int NbFaces = Quantities.length();
00788   std::vector<int> q (NbFaces);
00789   for (int j = 0; j < NbFaces; j++)
00790     q[j] = Quantities[j];
00791 
00792   const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(n, q);
00793 
00794   // Update Python script
00795   TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
00796                 << IDsOfNodes << ", " << Quantities << " )";
00797   myMesh->GetMeshDS()->Modified();
00798 
00799   return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
00800 }
00801 
00802 //=============================================================================
00806 //=============================================================================
00807 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
00808 {
00809   initData();
00810 
00811   int NbFaces = IdsOfFaces.length();
00812   std::vector<const SMDS_MeshNode*> poly_nodes;
00813   std::vector<int> quantities (NbFaces);
00814 
00815   for (int i = 0; i < NbFaces; i++) {
00816     const SMDS_MeshElement* aFace = GetMeshDS()->FindElement(IdsOfFaces[i]);
00817     quantities[i] = aFace->NbNodes();
00818 
00819     SMDS_ElemIteratorPtr It = aFace->nodesIterator();
00820     while (It->more()) {
00821       poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
00822     }
00823   }
00824 
00825   const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
00826 
00827   // Update Python script
00828   TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
00829                 << IdsOfFaces << " )";
00830   myMesh->GetMeshDS()->Modified();
00831 
00832   return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
00833 }
00834 
00835 //=============================================================================
00842 //=============================================================================
00843 
00844 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
00845   throw (SALOME::SALOME_Exception)
00846 {
00847   Unexpect aCatch(SALOME_SalomeException);
00848 
00849   SMESHDS_Mesh * mesh = GetMeshDS();
00850   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
00851   if ( !node )
00852     THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
00853 
00854   if ( mesh->MaxShapeIndex() < VertexID )
00855     THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
00856 
00857   TopoDS_Shape shape = mesh->IndexToShape( VertexID );
00858   if ( shape.ShapeType() != TopAbs_VERTEX )
00859     THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
00860 
00861   mesh->SetNodeOnVertex( node, VertexID );
00862 
00863   myMesh->SetIsModified( true );
00864 }
00865 
00866 //=============================================================================
00874 //=============================================================================
00875 
00876 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
00877                                        CORBA::Double paramOnEdge)
00878   throw (SALOME::SALOME_Exception)
00879 {
00880   Unexpect aCatch(SALOME_SalomeException);
00881 
00882   SMESHDS_Mesh * mesh = GetMeshDS();
00883   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
00884   if ( !node )
00885     THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
00886 
00887   if ( mesh->MaxShapeIndex() < EdgeID )
00888     THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
00889 
00890   TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
00891   if ( shape.ShapeType() != TopAbs_EDGE )
00892     THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
00893 
00894   Standard_Real f,l;
00895   BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
00896   if ( paramOnEdge < f || paramOnEdge > l )
00897     THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
00898 
00899   mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
00900 
00901   myMesh->SetIsModified( true );
00902 }
00903 
00904 //=============================================================================
00913 //=============================================================================
00914 
00915 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
00916                                        CORBA::Double u, CORBA::Double v)
00917   throw (SALOME::SALOME_Exception)
00918 {
00919   Unexpect aCatch(SALOME_SalomeException);
00920 
00921   SMESHDS_Mesh * mesh = GetMeshDS();
00922   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
00923   if ( !node )
00924     THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
00925 
00926   if ( mesh->MaxShapeIndex() < FaceID )
00927     THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
00928 
00929   TopoDS_Shape shape = mesh->IndexToShape( FaceID );
00930   if ( shape.ShapeType() != TopAbs_FACE )
00931     THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
00932 
00933   BRepAdaptor_Surface surf( TopoDS::Face( shape ));
00934   bool isOut = ( u < surf.FirstUParameter() ||
00935                  u > surf.LastUParameter()  ||
00936                  v < surf.FirstVParameter() ||
00937                  v > surf.LastVParameter() );
00938 
00939   if ( isOut ) {
00940 #ifdef _DEBUG_
00941     MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
00942               << " u( " <<  surf.FirstUParameter()
00943               << "," <<  surf.LastUParameter()
00944               << ") v( " <<  surf.FirstVParameter()
00945               << "," <<  surf.LastVParameter() << ")" );
00946 #endif
00947     THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
00948   }
00949 
00950   mesh->SetNodeOnFace( node, FaceID, u, v );
00951   myMesh->SetIsModified( true );
00952 }
00953 
00954 //=============================================================================
00961 //=============================================================================
00962 
00963 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
00964   throw (SALOME::SALOME_Exception)
00965 {
00966   Unexpect aCatch(SALOME_SalomeException);
00967 
00968   SMESHDS_Mesh * mesh = GetMeshDS();
00969   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
00970   if ( !node )
00971     THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
00972 
00973   if ( mesh->MaxShapeIndex() < SolidID )
00974     THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
00975 
00976   TopoDS_Shape shape = mesh->IndexToShape( SolidID );
00977   if ( shape.ShapeType() != TopAbs_SOLID &&
00978        shape.ShapeType() != TopAbs_SHELL)
00979     THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
00980 
00981   mesh->SetNodeInVolume( node, SolidID );
00982 
00983   // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe
00984 }
00985 
00986 //=============================================================================
00993 //=============================================================================
00994 
00995 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
00996                                                CORBA::Long ShapeID)
00997   throw (SALOME::SALOME_Exception)
00998 {
00999   Unexpect aCatch(SALOME_SalomeException);
01000 
01001   SMESHDS_Mesh * mesh = GetMeshDS();
01002   SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
01003   if ( !elem )
01004     THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
01005 
01006   if ( mesh->MaxShapeIndex() < ShapeID )
01007     THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
01008 
01009   TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
01010   if ( shape.ShapeType() != TopAbs_EDGE &&
01011        shape.ShapeType() != TopAbs_FACE &&
01012        shape.ShapeType() != TopAbs_SOLID &&
01013        shape.ShapeType() != TopAbs_SHELL )
01014     THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
01015 
01016   mesh->SetMeshElementOnShape( elem, ShapeID );
01017 
01018   myMesh->SetIsModified( true );
01019 }
01020 
01021 //=============================================================================
01025 //=============================================================================
01026 
01027 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
01028                                                CORBA::Long NodeID2)
01029 {
01030   initData();
01031 
01032   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
01033   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
01034   if ( !n1 || !n2 )
01035     return false;
01036 
01037   // Update Python script
01038   TPythonDump() << "isDone = " << this << ".InverseDiag( "
01039                 << NodeID1 << ", " << NodeID2 << " )";
01040 
01041 
01042   ::SMESH_MeshEditor aMeshEditor( myMesh );
01043   int ret =  aMeshEditor.InverseDiag ( n1, n2 );
01044   myMesh->GetMeshDS()->Modified();
01045   myMesh->SetIsModified( true );
01046   return ret;
01047 }
01048 
01049 //=============================================================================
01053 //=============================================================================
01054 
01055 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
01056                                               CORBA::Long NodeID2)
01057 {
01058   initData();
01059 
01060   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
01061   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
01062   if ( !n1 || !n2 )
01063     return false;
01064 
01065   // Update Python script
01066   TPythonDump() << "isDone = " << this << ".DeleteDiag( "
01067                 << NodeID1 << ", " << NodeID2 <<  " )";
01068 
01069   ::SMESH_MeshEditor aMeshEditor( myMesh );
01070 
01071   bool stat = aMeshEditor.DeleteDiag ( n1, n2 );
01072 
01073   myMesh->GetMeshDS()->Modified();
01074   if ( stat )
01075     myMesh->SetIsModified( true ); // issue 0020693
01076 
01077   storeResult(aMeshEditor);
01078 
01079   return stat;
01080 }
01081 
01082 //=============================================================================
01086 //=============================================================================
01087 
01088 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
01089 {
01090   initData();
01091 
01092   ::SMESH_MeshEditor anEditor( myMesh );
01093   for (int i = 0; i < IDsOfElements.length(); i++)
01094   {
01095     CORBA::Long index = IDsOfElements[i];
01096     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
01097     if ( elem )
01098       anEditor.Reorient( elem );
01099   }
01100   // Update Python script
01101   TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
01102 
01103   myMesh->GetMeshDS()->Modified();
01104   if ( IDsOfElements.length() )
01105     myMesh->SetIsModified( true ); // issue 0020693
01106 
01107   return true;
01108 }
01109 
01110 
01111 //=============================================================================
01115 //=============================================================================
01116 
01117 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
01118 {
01119   initData();
01120 
01121   TPythonDump aTPythonDump; // suppress dump in Reorient()
01122 
01123   SMESH::long_array_var anElementsId = theObject->GetIDs();
01124   CORBA::Boolean isDone = Reorient(anElementsId);
01125 
01126   // Update Python script
01127   aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
01128 
01129   return isDone;
01130 }
01131 
01132 //=============================================================================
01136 //=============================================================================
01137 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array &   IDsOfElements,
01138                                               SMESH::NumericalFunctor_ptr Criterion,
01139                                               CORBA::Double               MaxAngle)
01140 {
01141   initData();
01142 
01143   SMESHDS_Mesh* aMesh = GetMeshDS();
01144   TIDSortedElemSet faces;
01145   arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
01146 
01147   SMESH::NumericalFunctor_i* aNumericalFunctor =
01148     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
01149   SMESH::Controls::NumericalFunctorPtr aCrit;
01150   if ( !aNumericalFunctor )
01151     aCrit.reset( new SMESH::Controls::AspectRatio() );
01152   else
01153     aCrit = aNumericalFunctor->GetNumericalFunctor();
01154 
01155   // Update Python script
01156   TPythonDump() << "isDone = " << this << ".TriToQuad( "
01157                 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
01158 
01159   ::SMESH_MeshEditor anEditor( myMesh );
01160 
01161   bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle );
01162   myMesh->GetMeshDS()->Modified();
01163   if ( stat )
01164     myMesh->SetIsModified( true ); // issue 0020693
01165 
01166   storeResult(anEditor);
01167 
01168   return stat;
01169 }
01170 
01171 
01172 //=============================================================================
01176 //=============================================================================
01177 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr   theObject,
01178                                                     SMESH::NumericalFunctor_ptr Criterion,
01179                                                     CORBA::Double               MaxAngle)
01180 {
01181   initData();
01182 
01183   TPythonDump aTPythonDump;  // suppress dump in TriToQuad()
01184   SMESH::long_array_var anElementsId = theObject->GetIDs();
01185   CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
01186 
01187   SMESH::NumericalFunctor_i* aNumericalFunctor =
01188     SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
01189 
01190   // Update Python script
01191   aTPythonDump << "isDone = " << this << ".TriToQuadObject("
01192                << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
01193 
01194   return isDone;
01195 }
01196 
01197 
01198 //=============================================================================
01202 //=============================================================================
01203 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array &   IDsOfElements,
01204                                               SMESH::NumericalFunctor_ptr Criterion)
01205 {
01206   initData();
01207 
01208   SMESHDS_Mesh* aMesh = GetMeshDS();
01209   TIDSortedElemSet faces;
01210   arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
01211 
01212   SMESH::NumericalFunctor_i* aNumericalFunctor =
01213     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
01214   SMESH::Controls::NumericalFunctorPtr aCrit;
01215   if ( !aNumericalFunctor )
01216     aCrit.reset( new SMESH::Controls::AspectRatio() );
01217   else
01218     aCrit = aNumericalFunctor->GetNumericalFunctor();
01219 
01220 
01221   // Update Python script
01222   TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
01223 
01224   ::SMESH_MeshEditor anEditor( myMesh );
01225   CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit );
01226   myMesh->GetMeshDS()->Modified();
01227   if ( stat )
01228     myMesh->SetIsModified( true ); // issue 0020693
01229 
01230   storeResult(anEditor);
01231 
01232   return stat;
01233 }
01234 
01235 
01236 //=============================================================================
01240 //=============================================================================
01241 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr   theObject,
01242                                                     SMESH::NumericalFunctor_ptr Criterion)
01243 {
01244   initData();
01245 
01246   TPythonDump aTPythonDump;  // suppress dump in QuadToTri()
01247 
01248   SMESH::long_array_var anElementsId = theObject->GetIDs();
01249   CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
01250 
01251   SMESH::NumericalFunctor_i* aNumericalFunctor =
01252     SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
01253 
01254   // Update Python script
01255   aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
01256 
01257   return isDone;
01258 }
01259 
01260 
01261 //=============================================================================
01265 //=============================================================================
01266 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
01267                                               CORBA::Boolean            Diag13)
01268 {
01269   initData();
01270 
01271   SMESHDS_Mesh* aMesh = GetMeshDS();
01272   TIDSortedElemSet faces;
01273   arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
01274 
01275   // Update Python script
01276   TPythonDump() << "isDone = " << this << ".SplitQuad( "
01277                 << IDsOfElements << ", " << Diag13 << " )";
01278 
01279   ::SMESH_MeshEditor anEditor( myMesh );
01280   CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 );
01281   myMesh->GetMeshDS()->Modified();
01282   if ( stat )
01283     myMesh->SetIsModified( true ); // issue 0020693
01284 
01285 
01286   storeResult(anEditor);
01287 
01288   return stat;
01289 }
01290 
01291 
01292 //=============================================================================
01296 //=============================================================================
01297 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
01298                                                     CORBA::Boolean            Diag13)
01299 {
01300   initData();
01301 
01302   TPythonDump aTPythonDump;  // suppress dump in SplitQuad()
01303 
01304   SMESH::long_array_var anElementsId = theObject->GetIDs();
01305   CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
01306 
01307   // Update Python script
01308   aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
01309                << theObject << ", " << Diag13 << " )";
01310 
01311   return isDone;
01312 }
01313 
01314 
01315 //=============================================================================
01319 //=============================================================================
01320 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long                 IDOfQuad,
01321                                            SMESH::NumericalFunctor_ptr Criterion)
01322 {
01323   initData();
01324 
01325   const SMDS_MeshElement* quad = GetMeshDS()->FindElement(IDOfQuad);
01326   if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
01327   {
01328     SMESH::NumericalFunctor_i* aNumericalFunctor =
01329       dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
01330     SMESH::Controls::NumericalFunctorPtr aCrit;
01331     if (aNumericalFunctor)
01332       aCrit = aNumericalFunctor->GetNumericalFunctor();
01333     else
01334       aCrit.reset(new SMESH::Controls::AspectRatio());
01335 
01336     ::SMESH_MeshEditor anEditor (myMesh);
01337     return anEditor.BestSplit(quad, aCrit);
01338   }
01339   return -1;
01340 }
01341 
01342 //================================================================================
01346 //================================================================================
01347 
01348 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
01349                                                 CORBA::Short              methodFlags)
01350   throw (SALOME::SALOME_Exception)
01351 {
01352   Unexpect aCatch(SALOME_SalomeException);
01353 
01354   initData();
01355 
01356   SMESH::long_array_var anElementsId = elems->GetIDs();
01357   TIDSortedElemSet elemSet;
01358   arrayToSet( anElementsId, GetMeshDS(), elemSet, SMDSAbs_Volume );
01359 
01360   ::SMESH_MeshEditor anEditor (myMesh);
01361   anEditor.SplitVolumesIntoTetra( elemSet, int( methodFlags ));
01362   myMesh->GetMeshDS()->Modified();
01363 
01364   storeResult(anEditor);
01365 
01366 //   if ( myLastCreatedElems.length() ) - it does not influence Compute()
01367 //     myMesh->SetIsModified( true ); // issue 0020693
01368 
01369   TPythonDump() << this << ".SplitVolumesIntoTetra( "
01370                 << elems << ", " << methodFlags << " )";
01371 }
01372 
01373 //=======================================================================
01374 //function : Smooth
01375 //purpose  :
01376 //=======================================================================
01377 
01378 CORBA::Boolean
01379 SMESH_MeshEditor_i::Smooth(const SMESH::long_array &              IDsOfElements,
01380                            const SMESH::long_array &              IDsOfFixedNodes,
01381                            CORBA::Long                            MaxNbOfIterations,
01382                            CORBA::Double                          MaxAspectRatio,
01383                            SMESH::SMESH_MeshEditor::Smooth_Method Method)
01384 {
01385   return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
01386                  MaxAspectRatio, Method, false );
01387 }
01388 
01389 
01390 //=======================================================================
01391 //function : SmoothParametric
01392 //purpose  :
01393 //=======================================================================
01394 
01395 CORBA::Boolean
01396 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array &              IDsOfElements,
01397                                      const SMESH::long_array &              IDsOfFixedNodes,
01398                                      CORBA::Long                            MaxNbOfIterations,
01399                                      CORBA::Double                          MaxAspectRatio,
01400                                      SMESH::SMESH_MeshEditor::Smooth_Method Method)
01401 {
01402   return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
01403                  MaxAspectRatio, Method, true );
01404 }
01405 
01406 
01407 //=======================================================================
01408 //function : SmoothObject
01409 //purpose  :
01410 //=======================================================================
01411 
01412 CORBA::Boolean
01413 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr              theObject,
01414                                  const SMESH::long_array &              IDsOfFixedNodes,
01415                                  CORBA::Long                            MaxNbOfIterations,
01416                                  CORBA::Double                          MaxAspectRatio,
01417                                  SMESH::SMESH_MeshEditor::Smooth_Method Method)
01418 {
01419   return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
01420                        MaxAspectRatio, Method, false);
01421 }
01422 
01423 
01424 //=======================================================================
01425 //function : SmoothParametricObject
01426 //purpose  :
01427 //=======================================================================
01428 
01429 CORBA::Boolean
01430 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr              theObject,
01431                                            const SMESH::long_array &              IDsOfFixedNodes,
01432                                            CORBA::Long                            MaxNbOfIterations,
01433                                            CORBA::Double                          MaxAspectRatio,
01434                                            SMESH::SMESH_MeshEditor::Smooth_Method Method)
01435 {
01436   return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
01437                        MaxAspectRatio, Method, true);
01438 }
01439 
01440 
01441 //=============================================================================
01445 //=============================================================================
01446 
01447 CORBA::Boolean
01448 SMESH_MeshEditor_i::smooth(const SMESH::long_array &              IDsOfElements,
01449                            const SMESH::long_array &              IDsOfFixedNodes,
01450                            CORBA::Long                            MaxNbOfIterations,
01451                            CORBA::Double                          MaxAspectRatio,
01452                            SMESH::SMESH_MeshEditor::Smooth_Method Method,
01453                            bool                                   IsParametric)
01454 {
01455   initData();
01456 
01457   SMESHDS_Mesh* aMesh = GetMeshDS();
01458 
01459   TIDSortedElemSet elements;
01460   arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
01461 
01462   set<const SMDS_MeshNode*> fixedNodes;
01463   for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
01464     CORBA::Long index = IDsOfFixedNodes[i];
01465     const SMDS_MeshNode * node = aMesh->FindNode(index);
01466     if ( node )
01467       fixedNodes.insert( node );
01468   }
01469   ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
01470   if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
01471     method = ::SMESH_MeshEditor::CENTROIDAL;
01472 
01473   ::SMESH_MeshEditor anEditor( myMesh );
01474   anEditor.Smooth(elements, fixedNodes, method,
01475                   MaxNbOfIterations, MaxAspectRatio, IsParametric );
01476 
01477   myMesh->GetMeshDS()->Modified();
01478   myMesh->SetIsModified( true ); // issue 0020693
01479 
01480   storeResult(anEditor);
01481 
01482   // Update Python script
01483   TPythonDump() << "isDone = " << this << "."
01484                 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
01485                 << IDsOfElements << ", "     << IDsOfFixedNodes << ", "
01486                 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
01487                 << "SMESH.SMESH_MeshEditor."
01488                 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
01489                      "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
01490 
01491   return true;
01492 }
01493 
01494 
01495 //=============================================================================
01499 //=============================================================================
01500 
01501 CORBA::Boolean
01502 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr              theObject,
01503                                  const SMESH::long_array &              IDsOfFixedNodes,
01504                                  CORBA::Long                            MaxNbOfIterations,
01505                                  CORBA::Double                          MaxAspectRatio,
01506                                  SMESH::SMESH_MeshEditor::Smooth_Method Method,
01507                                  bool                                   IsParametric)
01508 {
01509   initData();
01510 
01511   TPythonDump aTPythonDump;  // suppress dump in smooth()
01512 
01513   SMESH::long_array_var anElementsId = theObject->GetIDs();
01514   CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
01515                                   MaxAspectRatio, Method, IsParametric);
01516 
01517   // Update Python script
01518   aTPythonDump << "isDone = " << this << "."
01519                << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
01520                << theObject << ", " << IDsOfFixedNodes << ", "
01521                << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
01522                << "SMESH.SMESH_MeshEditor."
01523                << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
01524                     "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
01525 
01526   return isDone;
01527 }
01528 
01529 
01530 //=============================================================================
01534 //=============================================================================
01535 
01536 void SMESH_MeshEditor_i::RenumberNodes()
01537 {
01538   // Update Python script
01539   TPythonDump() << this << ".RenumberNodes()";
01540 
01541   GetMeshDS()->Renumber( true );
01542 }
01543 
01544 
01545 //=============================================================================
01549 //=============================================================================
01550 
01551 void SMESH_MeshEditor_i::RenumberElements()
01552 {
01553   // Update Python script
01554   TPythonDump() << this << ".RenumberElements()";
01555 
01556   GetMeshDS()->Renumber( false );
01557 }
01558 
01559 //=======================================================================
01563 //=======================================================================
01564 
01565 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
01566 {
01567   if ( !groupIDs )
01568     return 0;
01569   myMesh_i->CreateGroupServants();
01570   return myMesh_i->GetGroups( *groupIDs );
01571 }
01572 
01573 //=======================================================================
01574 //function : rotationSweep
01575 //purpose  :
01576 //=======================================================================
01577 
01578 SMESH::ListOfGroups*
01579 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
01580                                   const SMESH::AxisStruct & theAxis,
01581                                   CORBA::Double             theAngleInRadians,
01582                                   CORBA::Long               theNbOfSteps,
01583                                   CORBA::Double             theTolerance,
01584                                   const bool                theMakeGroups,
01585                                   const SMDSAbs_ElementType theElementType)
01586 {
01587   initData();
01588 
01589   TIDSortedElemSet inElements, copyElements;
01590   arrayToSet(theIDsOfElements, GetMeshDS(), inElements, theElementType);
01591 
01592   TIDSortedElemSet* workElements = & inElements;
01593   TPreviewMesh      tmpMesh( SMDSAbs_Face );
01594   SMESH_Mesh*       mesh = 0;
01595   bool              makeWalls=true;
01596   if ( myPreviewMode )
01597   {
01598     SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
01599     tmpMesh.Copy( inElements, copyElements, select, avoid );
01600     mesh = &tmpMesh;
01601     workElements = & copyElements;
01602     //makeWalls = false;
01603   }
01604   else
01605   {
01606     mesh = myMesh;
01607   }
01608 
01609   gp_Ax1 Ax1 (gp_Pnt( theAxis.x,  theAxis.y,  theAxis.z ),
01610               gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
01611 
01612   ::SMESH_MeshEditor anEditor( mesh );
01613   ::SMESH_MeshEditor::PGroupIDs groupIds =
01614       anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
01615                               theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
01616   storeResult(anEditor);
01617   myMesh->GetMeshDS()->Modified();
01618 
01619   //  myMesh->SetIsModified( true ); -- it does not influence Compute()
01620 
01621   return theMakeGroups ? getGroups(groupIds.get()) : 0;
01622 }
01623 
01624 //=======================================================================
01625 //function : RotationSweep
01626 //purpose  :
01627 //=======================================================================
01628 
01629 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
01630                                        const SMESH::AxisStruct & theAxis,
01631                                        CORBA::Double             theAngleInRadians,
01632                                        CORBA::Long               theNbOfSteps,
01633                                        CORBA::Double             theTolerance)
01634 {
01635   if ( !myPreviewMode ) {
01636     TPythonDump() << this << ".RotationSweep( "
01637                   << theIDsOfElements          << ", "
01638                   << theAxis                   << ", "
01639                   << TVar( theAngleInRadians ) << ", "
01640                   << TVar( theNbOfSteps      ) << ", "
01641                   << TVar( theTolerance      ) << " )";
01642   }
01643   rotationSweep(theIDsOfElements,
01644                 theAxis,
01645                 theAngleInRadians,
01646                 theNbOfSteps,
01647                 theTolerance,
01648                 false);
01649 }
01650 
01651 //=======================================================================
01652 //function : RotationSweepMakeGroups
01653 //purpose  :
01654 //=======================================================================
01655 
01656 SMESH::ListOfGroups*
01657 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
01658                                             const SMESH::AxisStruct& theAxis,
01659                                             CORBA::Double            theAngleInRadians,
01660                                             CORBA::Long              theNbOfSteps,
01661                                             CORBA::Double            theTolerance)
01662 {
01663   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
01664 
01665   SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
01666                                                theAxis,
01667                                                theAngleInRadians,
01668                                                theNbOfSteps,
01669                                                theTolerance,
01670                                                true);
01671   if (!myPreviewMode) {
01672     DumpGroupsList(aPythonDump, aGroups);
01673     aPythonDump << this << ".RotationSweepMakeGroups( "
01674                 << theIDsOfElements        << ", "
01675                 << theAxis                   << ", "
01676                 << TVar( theAngleInRadians ) << ", "
01677                 << TVar( theNbOfSteps      ) << ", "
01678                 << TVar( theTolerance      ) << " )";
01679   }
01680   return aGroups;
01681 }
01682 
01683 //=======================================================================
01684 //function : RotationSweepObject
01685 //purpose  :
01686 //=======================================================================
01687 
01688 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
01689                                              const SMESH::AxisStruct & theAxis,
01690                                              CORBA::Double             theAngleInRadians,
01691                                              CORBA::Long               theNbOfSteps,
01692                                              CORBA::Double             theTolerance)
01693 {
01694   if ( !myPreviewMode ) {
01695     TPythonDump() << this << ".RotationSweepObject( "
01696                   << theObject << ", "
01697                   << theAxis << ", "
01698                   << theAngleInRadians << ", "
01699                   << theNbOfSteps << ", "
01700                   << theTolerance << " )";
01701   }
01702   SMESH::long_array_var anElementsId = theObject->GetIDs();
01703   rotationSweep(anElementsId,
01704                 theAxis,
01705                 theAngleInRadians,
01706                 theNbOfSteps,
01707                 theTolerance,
01708                 false);
01709 }
01710 
01711 //=======================================================================
01712 //function : RotationSweepObject1D
01713 //purpose  :
01714 //=======================================================================
01715 
01716 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
01717                                                const SMESH::AxisStruct & theAxis,
01718                                                CORBA::Double             theAngleInRadians,
01719                                                CORBA::Long               theNbOfSteps,
01720                                                CORBA::Double             theTolerance)
01721 {
01722   if ( !myPreviewMode ) {
01723     TPythonDump() << this << ".RotationSweepObject1D( "
01724                   << theObject                 << ", "
01725                   << theAxis                   << ", "
01726                   << TVar( theAngleInRadians ) << ", "
01727                   << TVar( theNbOfSteps      ) << ", "
01728                   << TVar( theTolerance      ) << " )";
01729   }
01730   SMESH::long_array_var anElementsId = theObject->GetIDs();
01731   rotationSweep(anElementsId,
01732                 theAxis,
01733                 theAngleInRadians,
01734                 theNbOfSteps,
01735                 theTolerance,
01736                 false,
01737                 SMDSAbs_Edge);
01738 }
01739 
01740 //=======================================================================
01741 //function : RotationSweepObject2D
01742 //purpose  :
01743 //=======================================================================
01744 
01745 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
01746                                                const SMESH::AxisStruct & theAxis,
01747                                                CORBA::Double             theAngleInRadians,
01748                                                CORBA::Long               theNbOfSteps,
01749                                                CORBA::Double             theTolerance)
01750 {
01751   if ( !myPreviewMode ) {
01752     TPythonDump() << this << ".RotationSweepObject2D( "
01753                   << theObject                 << ", "
01754                   << theAxis                   << ", "
01755                   << TVar( theAngleInRadians ) << ", "
01756                   << TVar( theNbOfSteps      ) << ", "
01757                   << TVar( theTolerance      ) << " )";
01758   }
01759   SMESH::long_array_var anElementsId = theObject->GetIDs();
01760   rotationSweep(anElementsId,
01761                 theAxis,
01762                 theAngleInRadians,
01763                 theNbOfSteps,
01764                 theTolerance,
01765                 false,
01766                 SMDSAbs_Face);
01767 }
01768 
01769 //=======================================================================
01770 //function : RotationSweepObjectMakeGroups
01771 //purpose  :
01772 //=======================================================================
01773 
01774 SMESH::ListOfGroups*
01775 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
01776                                                   const SMESH::AxisStruct&  theAxis,
01777                                                   CORBA::Double             theAngleInRadians,
01778                                                   CORBA::Long               theNbOfSteps,
01779                                                   CORBA::Double             theTolerance)
01780 {
01781   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
01782 
01783   SMESH::long_array_var anElementsId = theObject->GetIDs();
01784   SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
01785                                                theAxis,
01786                                                theAngleInRadians,
01787                                                theNbOfSteps,
01788                                                theTolerance,
01789                                                true);
01790   if (!myPreviewMode) {
01791     DumpGroupsList(aPythonDump, aGroups);
01792     aPythonDump << this << ".RotationSweepObjectMakeGroups( "
01793                 << theObject << ", "
01794                 << theAxis << ", "
01795                 << theAngleInRadians << ", "
01796                 << theNbOfSteps << ", "
01797                 << theTolerance << " )";
01798   }
01799   return aGroups;
01800 }
01801 
01802 //=======================================================================
01803 //function : RotationSweepObject1DMakeGroups
01804 //purpose  :
01805 //=======================================================================
01806 
01807 SMESH::ListOfGroups*
01808 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
01809                                                     const SMESH::AxisStruct&  theAxis,
01810                                                     CORBA::Double             theAngleInRadians,
01811                                                     CORBA::Long               theNbOfSteps,
01812                                                     CORBA::Double             theTolerance)
01813 {
01814   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
01815 
01816   SMESH::long_array_var anElementsId = theObject->GetIDs();
01817   SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
01818                                                theAxis,
01819                                                theAngleInRadians,
01820                                                theNbOfSteps,
01821                                                theTolerance,
01822                                                true,
01823                                                SMDSAbs_Edge);
01824   if (!myPreviewMode) {
01825     DumpGroupsList(aPythonDump, aGroups);
01826     aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
01827                 << theObject                 << ", "
01828                 << theAxis                   << ", "
01829                 << TVar( theAngleInRadians ) << ", "
01830                 << TVar( theNbOfSteps )      << ", "
01831                 << TVar( theTolerance )      << " )";
01832   }
01833   return aGroups;
01834 }
01835 
01836 //=======================================================================
01837 //function : RotationSweepObject2DMakeGroups
01838 //purpose  :
01839 //=======================================================================
01840 
01841 SMESH::ListOfGroups*
01842 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
01843                                                     const SMESH::AxisStruct&  theAxis,
01844                                                     CORBA::Double             theAngleInRadians,
01845                                                     CORBA::Long               theNbOfSteps,
01846                                                     CORBA::Double             theTolerance)
01847 {
01848   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
01849 
01850   SMESH::long_array_var anElementsId = theObject->GetIDs();
01851   SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
01852                                                theAxis,
01853                                                theAngleInRadians,
01854                                                theNbOfSteps,
01855                                                theTolerance,
01856                                                true,
01857                                                SMDSAbs_Face);
01858   if (!myPreviewMode) {
01859     DumpGroupsList(aPythonDump, aGroups);
01860     aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
01861                 << theObject                 << ", "
01862                 << theAxis                   << ", "
01863                 << TVar( theAngleInRadians ) << ", "
01864                 << TVar( theNbOfSteps      ) << ", "
01865                 << TVar( theTolerance      ) << " )";
01866   }
01867   return aGroups;
01868 }
01869 
01870 
01871 //=======================================================================
01872 //function : extrusionSweep
01873 //purpose  :
01874 //=======================================================================
01875 
01876 SMESH::ListOfGroups*
01877 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
01878                                    const SMESH::DirStruct &  theStepVector,
01879                                    CORBA::Long               theNbOfSteps,
01880                                    bool                      theMakeGroups,
01881                                    const SMDSAbs_ElementType theElementType)
01882 {
01883   initData();
01884 
01885   try {
01886 #ifdef NO_CAS_CATCH
01887     OCC_CATCH_SIGNALS;
01888 #endif
01889     TIDSortedElemSet elements, copyElements;
01890     arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
01891 
01892     const SMESH::PointStruct * P = &theStepVector.PS;
01893     gp_Vec stepVec( P->x, P->y, P->z );
01894 
01895     TIDSortedElemSet* workElements = & elements;
01896 
01897     SMDSAbs_ElementType aType = SMDSAbs_Face;
01898     //::SMESH_MeshEditor::ExtrusionFlags aFlag = ::SMESH_MeshEditor::ExtrusionFlags::EXTRUSION_FLAG_BOUNDARY;
01899     if (theElementType == SMDSAbs_Node)
01900     {
01901       aType = SMDSAbs_Edge;
01902       //aFlag = ::SMESH_MeshEditor::ExtrusionFlags::EXTRUSION_FLAG_SEW;
01903     }
01904     TPreviewMesh      tmpMesh( aType );
01905     SMESH_Mesh* mesh = myMesh;
01906 
01907     if ( myPreviewMode ) {
01908       SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
01909       tmpMesh.Copy( elements, copyElements, select, avoid );
01910       mesh = &tmpMesh;
01911       workElements = & copyElements;
01912       theMakeGroups = false;
01913     }
01914 
01915     TElemOfElemListMap aHystory;
01916     ::SMESH_MeshEditor anEditor( mesh );
01917     ::SMESH_MeshEditor::PGroupIDs groupIds = 
01918         anEditor.ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
01919 
01920     myMesh->GetMeshDS()->Modified();
01921     storeResult(anEditor);
01922 
01923     return theMakeGroups ? getGroups(groupIds.get()) : 0;
01924 
01925   } catch(Standard_Failure) {
01926     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01927     INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
01928   }
01929   return 0;
01930 }
01931 
01932 //=======================================================================
01933 //function : ExtrusionSweep
01934 //purpose  :
01935 //=======================================================================
01936 
01937 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
01938                                         const SMESH::DirStruct &  theStepVector,
01939                                         CORBA::Long               theNbOfSteps)
01940 {
01941   extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
01942   if (!myPreviewMode) {
01943     TPythonDump() << this << ".ExtrusionSweep( "
01944                   << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
01945   }
01946 }
01947 
01948 //=======================================================================
01949 //function : ExtrusionSweep0D
01950 //purpose  :
01951 //=======================================================================
01952 
01953 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
01954                                           const SMESH::DirStruct &  theStepVector,
01955                                           CORBA::Long               theNbOfSteps)
01956 {
01957   extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
01958   if (!myPreviewMode) {
01959     TPythonDump() << this << ".ExtrusionSweep0D( "
01960                   << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
01961   }
01962 }
01963 
01964 //=======================================================================
01965 //function : ExtrusionSweepObject
01966 //purpose  :
01967 //=======================================================================
01968 
01969 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
01970                                               const SMESH::DirStruct &  theStepVector,
01971                                               CORBA::Long               theNbOfSteps)
01972 {
01973   SMESH::long_array_var anElementsId = theObject->GetIDs();
01974   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
01975   if (!myPreviewMode) {
01976     TPythonDump() << this << ".ExtrusionSweepObject( "
01977                   << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
01978   }
01979 }
01980 
01981 //=======================================================================
01982 //function : ExtrusionSweepObject0D
01983 //purpose  :
01984 //=======================================================================
01985 
01986 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
01987                                                 const SMESH::DirStruct &  theStepVector,
01988                                                 CORBA::Long               theNbOfSteps)
01989 {
01990   SMESH::long_array_var anElementsId = theObject->GetIDs();
01991   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
01992   if ( !myPreviewMode ) {
01993     TPythonDump() << this << ".ExtrusionSweepObject0D( "
01994                   << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
01995   }
01996 }
01997 
01998 //=======================================================================
01999 //function : ExtrusionSweepObject1D
02000 //purpose  :
02001 //=======================================================================
02002 
02003 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
02004                                                 const SMESH::DirStruct &  theStepVector,
02005                                                 CORBA::Long               theNbOfSteps)
02006 {
02007   SMESH::long_array_var anElementsId = theObject->GetIDs();
02008   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
02009   if ( !myPreviewMode ) {
02010     TPythonDump() << this << ".ExtrusionSweepObject1D( "
02011                   << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
02012   }
02013 }
02014 
02015 //=======================================================================
02016 //function : ExtrusionSweepObject2D
02017 //purpose  :
02018 //=======================================================================
02019 
02020 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
02021                                                 const SMESH::DirStruct &  theStepVector,
02022                                                 CORBA::Long               theNbOfSteps)
02023 {
02024   SMESH::long_array_var anElementsId = theObject->GetIDs();
02025   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
02026   if ( !myPreviewMode ) {
02027     TPythonDump() << this << ".ExtrusionSweepObject2D( "
02028                   << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
02029   }
02030 }
02031 
02032 //=======================================================================
02033 //function : ExtrusionSweepMakeGroups
02034 //purpose  :
02035 //=======================================================================
02036 
02037 SMESH::ListOfGroups*
02038 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
02039                                              const SMESH::DirStruct&  theStepVector,
02040                                              CORBA::Long              theNbOfSteps)
02041 {
02042   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
02043 
02044   SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
02045 
02046   if (!myPreviewMode) {
02047     DumpGroupsList(aPythonDump, aGroups);
02048     aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
02049                 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
02050   }
02051   return aGroups;
02052 }
02053 
02054 //=======================================================================
02055 //function : ExtrusionSweepMakeGroups0D
02056 //purpose  :
02057 //=======================================================================
02058 
02059 SMESH::ListOfGroups*
02060 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
02061                                                const SMESH::DirStruct&  theStepVector,
02062                                                CORBA::Long              theNbOfSteps)
02063 {
02064   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
02065 
02066   SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
02067 
02068   if (!myPreviewMode) {
02069     DumpGroupsList(aPythonDump, aGroups);
02070     aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
02071                 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
02072   }
02073   return aGroups;
02074 }
02075 
02076 //=======================================================================
02077 //function : ExtrusionSweepObjectMakeGroups
02078 //purpose  :
02079 //=======================================================================
02080 
02081 SMESH::ListOfGroups*
02082 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
02083                                                    const SMESH::DirStruct&   theStepVector,
02084                                                    CORBA::Long               theNbOfSteps)
02085 {
02086   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
02087 
02088   SMESH::long_array_var anElementsId = theObject->GetIDs();
02089   SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
02090 
02091   if (!myPreviewMode) {
02092     DumpGroupsList(aPythonDump, aGroups);
02093     aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
02094                 << ", " << theStepVector << ", " << theNbOfSteps << " )";
02095   }
02096   return aGroups;
02097 }
02098 
02099 //=======================================================================
02100 //function : ExtrusionSweepObject0DMakeGroups
02101 //purpose  :
02102 //=======================================================================
02103 
02104 SMESH::ListOfGroups*
02105 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
02106                                                      const SMESH::DirStruct&   theStepVector,
02107                                                      CORBA::Long               theNbOfSteps)
02108 {
02109   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
02110 
02111   SMESH::long_array_var anElementsId = theObject->GetIDs();
02112   SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
02113                                                  theNbOfSteps, true, SMDSAbs_Node);
02114   if (!myPreviewMode) {
02115     DumpGroupsList(aPythonDump, aGroups);
02116     aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
02117                 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
02118   }
02119   return aGroups;
02120 }
02121 
02122 //=======================================================================
02123 //function : ExtrusionSweepObject1DMakeGroups
02124 //purpose  :
02125 //=======================================================================
02126 
02127 SMESH::ListOfGroups*
02128 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
02129                                                      const SMESH::DirStruct&   theStepVector,
02130                                                      CORBA::Long               theNbOfSteps)
02131 {
02132   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
02133 
02134   SMESH::long_array_var anElementsId = theObject->GetIDs();
02135   SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
02136                                                  theNbOfSteps, true, SMDSAbs_Edge);
02137   if (!myPreviewMode) {
02138     DumpGroupsList(aPythonDump, aGroups);
02139     aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
02140                 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
02141   }
02142   return aGroups;
02143 }
02144 
02145 //=======================================================================
02146 //function : ExtrusionSweepObject2DMakeGroups
02147 //purpose  :
02148 //=======================================================================
02149 
02150 SMESH::ListOfGroups*
02151 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
02152                                                      const SMESH::DirStruct&   theStepVector,
02153                                                      CORBA::Long               theNbOfSteps)
02154 {
02155   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
02156 
02157   SMESH::long_array_var anElementsId = theObject->GetIDs();
02158   SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
02159                                                  theNbOfSteps, true, SMDSAbs_Face);
02160   if (!myPreviewMode) {
02161     DumpGroupsList(aPythonDump, aGroups);
02162     aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
02163                 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
02164   }
02165   return aGroups;
02166 }
02167 
02168 
02169 //=======================================================================
02170 //function : advancedExtrusion
02171 //purpose  :
02172 //=======================================================================
02173 
02174 SMESH::ListOfGroups*
02175 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
02176                                       const SMESH::DirStruct &  theStepVector,
02177                                       CORBA::Long               theNbOfSteps,
02178                                       CORBA::Long               theExtrFlags,
02179                                       CORBA::Double             theSewTolerance,
02180                                       const bool                theMakeGroups)
02181 {
02182   initData();
02183 
02184   TIDSortedElemSet elements;
02185   arrayToSet(theIDsOfElements, GetMeshDS(), elements);
02186 
02187   const SMESH::PointStruct * P = &theStepVector.PS;
02188   gp_Vec stepVec( P->x, P->y, P->z );
02189 
02190   ::SMESH_MeshEditor anEditor( myMesh );
02191   TElemOfElemListMap aHystory;
02192   ::SMESH_MeshEditor::PGroupIDs groupIds =
02193       anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
02194                                theMakeGroups, theExtrFlags, theSewTolerance);
02195   storeResult(anEditor);
02196 
02197   return theMakeGroups ? getGroups(groupIds.get()) : 0;
02198 }
02199 
02200 //=======================================================================
02201 //function : AdvancedExtrusion
02202 //purpose  :
02203 //=======================================================================
02204 
02205 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
02206                                            const SMESH::DirStruct &  theStepVector,
02207                                            CORBA::Long               theNbOfSteps,
02208                                            CORBA::Long               theExtrFlags,
02209                                            CORBA::Double             theSewTolerance)
02210 {
02211   if ( !myPreviewMode ) {
02212     TPythonDump() << "stepVector = " << theStepVector;
02213     TPythonDump() << this << ".AdvancedExtrusion("
02214                   << theIDsOfElements
02215                   << ", stepVector, "
02216                   << theNbOfSteps << ","
02217                   << theExtrFlags << ", "
02218                   << theSewTolerance <<  " )";
02219   }
02220   advancedExtrusion( theIDsOfElements,
02221                      theStepVector,
02222                      theNbOfSteps,
02223                      theExtrFlags,
02224                      theSewTolerance,
02225                      false);
02226 }
02227 
02228 //=======================================================================
02229 //function : AdvancedExtrusionMakeGroups
02230 //purpose  :
02231 //=======================================================================
02232 SMESH::ListOfGroups*
02233 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
02234                                                 const SMESH::DirStruct&  theStepVector,
02235                                                 CORBA::Long              theNbOfSteps,
02236                                                 CORBA::Long              theExtrFlags,
02237                                                 CORBA::Double            theSewTolerance)
02238 {
02239   if (!myPreviewMode) {
02240     TPythonDump() << "stepVector = " << theStepVector;
02241   }
02242   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
02243 
02244   SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
02245                                                      theStepVector,
02246                                                      theNbOfSteps,
02247                                                      theExtrFlags,
02248                                                      theSewTolerance,
02249                                                      true);
02250 
02251   if (!myPreviewMode) {
02252     DumpGroupsList(aPythonDump, aGroups);
02253     aPythonDump << this << ".AdvancedExtrusionMakeGroups("
02254                 << theIDsOfElements
02255                 << ", stepVector, "
02256                 << theNbOfSteps << ","
02257                 << theExtrFlags << ", "
02258                 << theSewTolerance <<  " )";
02259   }
02260   return aGroups;
02261 }
02262 
02263 
02264 //================================================================================
02268 //================================================================================
02269 
02270 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
02271 
02272 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
02273 {
02274   switch ( e ) {
02275     RETCASE( EXTR_OK );
02276     RETCASE( EXTR_NO_ELEMENTS );
02277     RETCASE( EXTR_PATH_NOT_EDGE );
02278     RETCASE( EXTR_BAD_PATH_SHAPE );
02279     RETCASE( EXTR_BAD_STARTING_NODE );
02280     RETCASE( EXTR_BAD_ANGLES_NUMBER );
02281     RETCASE( EXTR_CANT_GET_TANGENT );
02282   }
02283   return SMESH::SMESH_MeshEditor::EXTR_OK;
02284 }
02285 
02286 
02287 //=======================================================================
02288 //function : extrusionAlongPath
02289 //purpose  :
02290 //=======================================================================
02291 SMESH::ListOfGroups*
02292 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array &   theIDsOfElements,
02293                                        SMESH::SMESH_Mesh_ptr       thePathMesh,
02294                                        GEOM::GEOM_Object_ptr       thePathShape,
02295                                        CORBA::Long                 theNodeStart,
02296                                        CORBA::Boolean              theHasAngles,
02297                                        const SMESH::double_array & theAngles,
02298                                        CORBA::Boolean              theHasRefPoint,
02299                                        const SMESH::PointStruct &  theRefPoint,
02300                                        const bool                  theMakeGroups,
02301                                        SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
02302                                        const SMDSAbs_ElementType   theElementType)
02303 {
02304   MESSAGE("extrusionAlongPath");
02305   initData();
02306 
02307   if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
02308     theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
02309     return 0;
02310   }
02311   SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
02312 
02313   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
02314   SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
02315 
02316   if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
02317     theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
02318     return 0;
02319   }
02320 
02321   SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
02322   if ( !nodeStart ) {
02323     theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
02324     return 0;
02325   }
02326 
02327   TIDSortedElemSet elements;
02328   arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
02329 
02330   list<double> angles;
02331   for (int i = 0; i < theAngles.length(); i++) {
02332     angles.push_back( theAngles[i] );
02333   }
02334 
02335   gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
02336 
02337   int nbOldGroups = myMesh->NbGroup();
02338 
02339   ::SMESH_MeshEditor anEditor( myMesh );
02340   ::SMESH_MeshEditor::Extrusion_Error error =
02341       anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
02342                                     theHasAngles, angles, false,
02343                                     theHasRefPoint, refPnt, theMakeGroups );
02344   myMesh->GetMeshDS()->Modified();
02345   storeResult(anEditor);
02346   theError = convExtrError( error );
02347 
02348   if ( theMakeGroups ) {
02349     list<int> groupIDs = myMesh->GetGroupIds();
02350     list<int>::iterator newBegin = groupIDs.begin();
02351     std::advance( newBegin, nbOldGroups ); // skip old groups
02352     groupIDs.erase( groupIDs.begin(), newBegin );
02353     return getGroups( & groupIDs );
02354   }
02355   return 0;
02356 }
02357 
02358 
02359 //=======================================================================
02360 //function : extrusionAlongPathX
02361 //purpose  :
02362 //=======================================================================
02363 SMESH::ListOfGroups*
02364 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array &  IDsOfElements,
02365                                         SMESH::SMESH_IDSource_ptr  Path,
02366                                         CORBA::Long                NodeStart,
02367                                         CORBA::Boolean             HasAngles,
02368                                         const SMESH::double_array& Angles,
02369                                         CORBA::Boolean             LinearVariation,
02370                                         CORBA::Boolean             HasRefPoint,
02371                                         const SMESH::PointStruct&  RefPoint,
02372                                         bool                       MakeGroups,
02373                                         const SMDSAbs_ElementType  ElementType,
02374                                         SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
02375 {
02376   SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
02377 
02378   initData();
02379 
02380   list<double> angles;
02381   for (int i = 0; i < Angles.length(); i++) {
02382     angles.push_back( Angles[i] );
02383   }
02384   gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
02385   int nbOldGroups = myMesh->NbGroup();
02386 
02387   if ( Path->_is_nil() ) {
02388     Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
02389     return EmptyGr;
02390   }
02391 
02392   TIDSortedElemSet elements, copyElements;
02393   arrayToSet(IDsOfElements, GetMeshDS(), elements, ElementType);
02394 
02395   TIDSortedElemSet* workElements = &elements;
02396   TPreviewMesh      tmpMesh( SMDSAbs_Face );
02397   SMESH_Mesh*       mesh = myMesh;
02398 
02399   if ( myPreviewMode )
02400   {
02401     SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
02402     tmpMesh.Copy( elements, copyElements, select, avoid );
02403     mesh = &tmpMesh;
02404     workElements = & copyElements;
02405     MakeGroups = false;
02406   }
02407 
02408   ::SMESH_MeshEditor anEditor( mesh );
02409   ::SMESH_MeshEditor::Extrusion_Error error;
02410 
02411   if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
02412   {
02413     // path as mesh
02414     SMDS_MeshNode* aNodeStart =
02415       (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
02416     if ( !aNodeStart ) {
02417       Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
02418       return EmptyGr;
02419     }
02420     error = anEditor.ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
02421                                           HasAngles, angles, LinearVariation,
02422                                           HasRefPoint, refPnt, MakeGroups );
02423     myMesh->GetMeshDS()->Modified();
02424   }
02425   else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
02426   {
02427     // path as submesh
02428     SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
02429     aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
02430     SMDS_MeshNode* aNodeStart =
02431       (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
02432     if ( !aNodeStart ) {
02433       Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
02434       return EmptyGr;
02435     }
02436     SMESH_subMesh* aSubMesh =
02437       aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
02438     error = anEditor.ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
02439                                           HasAngles, angles, LinearVariation,
02440                                           HasRefPoint, refPnt, MakeGroups );
02441     myMesh->GetMeshDS()->Modified();
02442   }
02443   else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
02444   {
02445     // path as group of 1D elements
02446     // ????????
02447   }
02448   else
02449   {
02450     // invalid path
02451     Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
02452     return EmptyGr;
02453   }
02454 
02455   storeResult(anEditor);
02456   Error = convExtrError( error );
02457 
02458   if ( MakeGroups ) {
02459     list<int> groupIDs = myMesh->GetGroupIds();
02460     list<int>::iterator newBegin = groupIDs.begin();
02461     std::advance( newBegin, nbOldGroups ); // skip old groups
02462     groupIDs.erase( groupIDs.begin(), newBegin );
02463     return getGroups( & groupIDs );
02464   }
02465   return EmptyGr;
02466 }
02467 
02468 
02469 //=======================================================================
02470 //function : ExtrusionAlongPath
02471 //purpose  :
02472 //=======================================================================
02473 SMESH::SMESH_MeshEditor::Extrusion_Error
02474 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array &   theIDsOfElements,
02475                                        SMESH::SMESH_Mesh_ptr       thePathMesh,
02476                                        GEOM::GEOM_Object_ptr       thePathShape,
02477                                        CORBA::Long                 theNodeStart,
02478                                        CORBA::Boolean              theHasAngles,
02479                                        const SMESH::double_array & theAngles,
02480                                        CORBA::Boolean              theHasRefPoint,
02481                                        const SMESH::PointStruct &  theRefPoint)
02482 {
02483   MESSAGE("ExtrusionAlongPath");
02484   if ( !myPreviewMode ) {
02485     TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
02486                   << theIDsOfElements << ", "
02487                   << thePathMesh      << ", "
02488                   << thePathShape     << ", "
02489                   << theNodeStart     << ", "
02490                   << theHasAngles     << ", "
02491                   << theAngles        << ", "
02492                   << theHasRefPoint   << ", "
02493                   << "SMESH.PointStruct( "
02494                   << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
02495                   << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
02496                   << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
02497   }
02498   SMESH::SMESH_MeshEditor::Extrusion_Error anError;
02499   extrusionAlongPath( theIDsOfElements,
02500                       thePathMesh,
02501                       thePathShape,
02502                       theNodeStart,
02503                       theHasAngles,
02504                       theAngles,
02505                       theHasRefPoint,
02506                       theRefPoint,
02507                       false,
02508                       anError);
02509   return anError;
02510 }
02511 
02512 //=======================================================================
02513 //function : ExtrusionAlongPathObject
02514 //purpose  :
02515 //=======================================================================
02516 SMESH::SMESH_MeshEditor::Extrusion_Error
02517 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObject,
02518                                              SMESH::SMESH_Mesh_ptr       thePathMesh,
02519                                              GEOM::GEOM_Object_ptr       thePathShape,
02520                                              CORBA::Long                 theNodeStart,
02521                                              CORBA::Boolean              theHasAngles,
02522                                              const SMESH::double_array & theAngles,
02523                                              CORBA::Boolean              theHasRefPoint,
02524                                              const SMESH::PointStruct &  theRefPoint)
02525 {
02526   if ( !myPreviewMode ) {
02527     TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
02528                   << theObject        << ", "
02529                   << thePathMesh      << ", "
02530                   << thePathShape     << ", "
02531                   << theNodeStart     << ", "
02532                   << theHasAngles     << ", "
02533                   << theAngles        << ", "
02534                   << theHasRefPoint   << ", "
02535                   << "SMESH.PointStruct( "
02536                   << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
02537                   << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
02538                   << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
02539   }
02540   SMESH::SMESH_MeshEditor::Extrusion_Error anError;
02541   SMESH::long_array_var anElementsId = theObject->GetIDs();
02542   extrusionAlongPath( anElementsId,
02543                       thePathMesh,
02544                       thePathShape,
02545                       theNodeStart,
02546                       theHasAngles,
02547                       theAngles,
02548                       theHasRefPoint,
02549                       theRefPoint,
02550                       false,
02551                       anError);
02552   return anError;
02553 }
02554 
02555 //=======================================================================
02556 //function : ExtrusionAlongPathObject1D
02557 //purpose  :
02558 //=======================================================================
02559 SMESH::SMESH_MeshEditor::Extrusion_Error
02560 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr   theObject,
02561                                                SMESH::SMESH_Mesh_ptr       thePathMesh,
02562                                                GEOM::GEOM_Object_ptr       thePathShape,
02563                                                CORBA::Long                 theNodeStart,
02564                                                CORBA::Boolean              theHasAngles,
02565                                                const SMESH::double_array & theAngles,
02566                                                CORBA::Boolean              theHasRefPoint,
02567                                                const SMESH::PointStruct &  theRefPoint)
02568 {
02569   if ( !myPreviewMode ) {
02570     TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
02571                   << theObject        << ", "
02572                   << thePathMesh      << ", "
02573                   << thePathShape     << ", "
02574                   << theNodeStart     << ", "
02575                   << theHasAngles     << ", "
02576                   << theAngles        << ", "
02577                   << theHasRefPoint   << ", "
02578                   << "SMESH.PointStruct( "
02579                   << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
02580                   << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
02581                   << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
02582   }
02583   SMESH::SMESH_MeshEditor::Extrusion_Error anError;
02584   SMESH::long_array_var anElementsId = theObject->GetIDs();
02585   extrusionAlongPath( anElementsId,
02586                       thePathMesh,
02587                       thePathShape,
02588                       theNodeStart,
02589                       theHasAngles,
02590                       theAngles,
02591                       theHasRefPoint,
02592                       theRefPoint,
02593                       false,
02594                       anError,
02595                       SMDSAbs_Edge);
02596   return anError;
02597 }
02598 
02599 //=======================================================================
02600 //function : ExtrusionAlongPathObject2D
02601 //purpose  :
02602 //=======================================================================
02603 SMESH::SMESH_MeshEditor::Extrusion_Error
02604 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr   theObject,
02605                                                SMESH::SMESH_Mesh_ptr       thePathMesh,
02606                                                GEOM::GEOM_Object_ptr       thePathShape,
02607                                                CORBA::Long                 theNodeStart,
02608                                                CORBA::Boolean              theHasAngles,
02609                                                const SMESH::double_array & theAngles,
02610                                                CORBA::Boolean              theHasRefPoint,
02611                                                const SMESH::PointStruct &  theRefPoint)
02612 {
02613   if ( !myPreviewMode ) {
02614     TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
02615                   << theObject        << ", "
02616                   << thePathMesh      << ", "
02617                   << thePathShape     << ", "
02618                   << theNodeStart     << ", "
02619                   << theHasAngles     << ", "
02620                   << theAngles        << ", "
02621                   << theHasRefPoint   << ", "
02622                   << "SMESH.PointStruct( "
02623                   << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
02624                   << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
02625                   << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
02626   }
02627   SMESH::SMESH_MeshEditor::Extrusion_Error anError;
02628   SMESH::long_array_var anElementsId = theObject->GetIDs();
02629   extrusionAlongPath( anElementsId,
02630                       thePathMesh,
02631                       thePathShape,
02632                       theNodeStart,
02633                       theHasAngles,
02634                       theAngles,
02635                       theHasRefPoint,
02636                       theRefPoint,
02637                       false,
02638                       anError,
02639                       SMDSAbs_Face);
02640   return anError;
02641 }
02642 
02643 
02644 //=======================================================================
02645 //function : ExtrusionAlongPathMakeGroups
02646 //purpose  :
02647 //=======================================================================
02648 SMESH::ListOfGroups*
02649 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array&   theIDsOfElements,
02650                                                  SMESH::SMESH_Mesh_ptr      thePathMesh,
02651                                                  GEOM::GEOM_Object_ptr      thePathShape,
02652                                                  CORBA::Long                theNodeStart,
02653                                                  CORBA::Boolean             theHasAngles,
02654                                                  const SMESH::double_array& theAngles,
02655                                                  CORBA::Boolean             theHasRefPoint,
02656                                                  const SMESH::PointStruct&  theRefPoint,
02657                                                  SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
02658 {
02659   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
02660 
02661   SMESH::ListOfGroups * aGroups =  extrusionAlongPath( theIDsOfElements,
02662                                                        thePathMesh,
02663                                                        thePathShape,
02664                                                        theNodeStart,
02665                                                        theHasAngles,
02666                                                        theAngles,
02667                                                        theHasRefPoint,
02668                                                        theRefPoint,
02669                                                        true,
02670                                                        Error);
02671   if (!myPreviewMode) {
02672     bool isDumpGroups = aGroups && aGroups->length() > 0;
02673     if (isDumpGroups)
02674       aPythonDump << "(" << aGroups << ", error)";
02675     else
02676       aPythonDump <<"error";
02677 
02678     aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
02679                << theIDsOfElements << ", "
02680                << thePathMesh      << ", "
02681                << thePathShape     << ", "
02682                << theNodeStart     << ", "
02683                << theHasAngles     << ", "
02684                << theAngles        << ", "
02685                << theHasRefPoint   << ", "
02686                << "SMESH.PointStruct( "
02687                << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
02688                << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
02689                << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
02690   }
02691   return aGroups;
02692 }
02693 
02694 //=======================================================================
02695 //function : ExtrusionAlongPathObjectMakeGroups
02696 //purpose  :
02697 //=======================================================================
02698 SMESH::ListOfGroups* SMESH_MeshEditor_i::
02699 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
02700                                    SMESH::SMESH_Mesh_ptr      thePathMesh,
02701                                    GEOM::GEOM_Object_ptr      thePathShape,
02702                                    CORBA::Long                theNodeStart,
02703                                    CORBA::Boolean             theHasAngles,
02704                                    const SMESH::double_array& theAngles,
02705                                    CORBA::Boolean             theHasRefPoint,
02706                                    const SMESH::PointStruct&  theRefPoint,
02707                                    SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
02708 {
02709   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
02710 
02711   SMESH::long_array_var anElementsId = theObject->GetIDs();
02712   SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
02713                                                       thePathMesh,
02714                                                       thePathShape,
02715                                                       theNodeStart,
02716                                                       theHasAngles,
02717                                                       theAngles,
02718                                                       theHasRefPoint,
02719                                                       theRefPoint,
02720                                                       true,
02721                                                       Error);
02722 
02723   if (!myPreviewMode) {
02724     bool isDumpGroups = aGroups && aGroups->length() > 0;
02725     if (isDumpGroups)
02726       aPythonDump << "(" << aGroups << ", error)";
02727     else
02728       aPythonDump <<"error";
02729 
02730     aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
02731                 << theObject << ", "
02732                 << thePathMesh      << ", "
02733                 << thePathShape     << ", "
02734                 << theNodeStart     << ", "
02735                 << theHasAngles     << ", "
02736                 << theAngles        << ", "
02737                 << theHasRefPoint   << ", "
02738                 << "SMESH.PointStruct( "
02739                 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
02740                 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
02741                 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
02742   }
02743   return aGroups;
02744 }
02745 
02746 //=======================================================================
02747 //function : ExtrusionAlongPathObject1DMakeGroups
02748 //purpose  :
02749 //=======================================================================
02750 SMESH::ListOfGroups* SMESH_MeshEditor_i::
02751 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
02752                                      SMESH::SMESH_Mesh_ptr      thePathMesh,
02753                                      GEOM::GEOM_Object_ptr      thePathShape,
02754                                      CORBA::Long                theNodeStart,
02755                                      CORBA::Boolean             theHasAngles,
02756                                      const SMESH::double_array& theAngles,
02757                                      CORBA::Boolean             theHasRefPoint,
02758                                      const SMESH::PointStruct&  theRefPoint,
02759                                      SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
02760 {
02761   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
02762 
02763   SMESH::long_array_var anElementsId = theObject->GetIDs();
02764   SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
02765                                                       thePathMesh,
02766                                                       thePathShape,
02767                                                       theNodeStart,
02768                                                       theHasAngles,
02769                                                       theAngles,
02770                                                       theHasRefPoint,
02771                                                       theRefPoint,
02772                                                       true,
02773                                                       Error,
02774                                                       SMDSAbs_Edge);
02775 
02776   if (!myPreviewMode) {
02777     bool isDumpGroups = aGroups && aGroups->length() > 0;
02778     if (isDumpGroups)
02779       aPythonDump << "(" << aGroups << ", error)";
02780     else
02781       aPythonDump << "error";
02782 
02783     aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
02784                 << theObject << ", "
02785                 << thePathMesh      << ", "
02786                 << thePathShape     << ", "
02787                 << theNodeStart     << ", "
02788                 << theHasAngles     << ", "
02789                 << theAngles        << ", "
02790                 << theHasRefPoint   << ", "
02791                 << "SMESH.PointStruct( "
02792                 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
02793                 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
02794                 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
02795   }
02796   return aGroups;
02797 }
02798 
02799 //=======================================================================
02800 //function : ExtrusionAlongPathObject2DMakeGroups
02801 //purpose  :
02802 //=======================================================================
02803 SMESH::ListOfGroups* SMESH_MeshEditor_i::
02804 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
02805                                      SMESH::SMESH_Mesh_ptr      thePathMesh,
02806                                      GEOM::GEOM_Object_ptr      thePathShape,
02807                                      CORBA::Long                theNodeStart,
02808                                      CORBA::Boolean             theHasAngles,
02809                                      const SMESH::double_array& theAngles,
02810                                      CORBA::Boolean             theHasRefPoint,
02811                                      const SMESH::PointStruct&  theRefPoint,
02812                                      SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
02813 {
02814   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
02815 
02816   SMESH::long_array_var anElementsId = theObject->GetIDs();
02817   SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
02818                                                       thePathMesh,
02819                                                       thePathShape,
02820                                                       theNodeStart,
02821                                                       theHasAngles,
02822                                                       theAngles,
02823                                                       theHasRefPoint,
02824                                                       theRefPoint,
02825                                                       true,
02826                                                       Error,
02827                                                       SMDSAbs_Face);
02828 
02829   if (!myPreviewMode) {
02830     bool isDumpGroups = aGroups && aGroups->length() > 0;
02831     if (isDumpGroups)
02832       aPythonDump << "(" << aGroups << ", error)";
02833     else
02834       aPythonDump << "error";
02835 
02836     aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
02837                 << theObject << ", "
02838                 << thePathMesh      << ", "
02839                 << thePathShape     << ", "
02840                 << theNodeStart     << ", "
02841                 << theHasAngles     << ", "
02842                 << theAngles        << ", "
02843                 << theHasRefPoint   << ", "
02844                 << "SMESH.PointStruct( "
02845                 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
02846                 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
02847                 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
02848   }
02849   return aGroups;
02850 }
02851 
02852 
02853 //=======================================================================
02854 //function : ExtrusionAlongPathObjX
02855 //purpose  :
02856 //=======================================================================
02857 SMESH::ListOfGroups* SMESH_MeshEditor_i::
02858 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr  Object,
02859                        SMESH::SMESH_IDSource_ptr  Path,
02860                        CORBA::Long                NodeStart,
02861                        CORBA::Boolean             HasAngles,
02862                        const SMESH::double_array& Angles,
02863                        CORBA::Boolean             LinearVariation,
02864                        CORBA::Boolean             HasRefPoint,
02865                        const SMESH::PointStruct&  RefPoint,
02866                        CORBA::Boolean             MakeGroups,
02867                        SMESH::ElementType         ElemType,
02868                        SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
02869 {
02870   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
02871 
02872   SMESH::long_array_var anElementsId = Object->GetIDs();
02873   SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
02874                                                       Path,
02875                                                       NodeStart,
02876                                                       HasAngles,
02877                                                       Angles,
02878                                                       LinearVariation,
02879                                                       HasRefPoint,
02880                                                       RefPoint,
02881                                                       MakeGroups,
02882                                                       (SMDSAbs_ElementType)ElemType,
02883                                                       Error);
02884 
02885   if (!myPreviewMode) {
02886     bool isDumpGroups = aGroups && aGroups->length() > 0;
02887     if (isDumpGroups)
02888       aPythonDump << "(" << *aGroups << ", error)";
02889     else
02890       aPythonDump << "error";
02891 
02892     aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
02893                 << Object          << ", "
02894                 << Path            << ", "
02895                 << NodeStart       << ", "
02896                 << HasAngles       << ", "
02897                 << TVar( Angles )  << ", "
02898                 << LinearVariation << ", "
02899                 << HasRefPoint     << ", "
02900                 << "SMESH.PointStruct( "
02901                 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
02902                 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
02903                 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
02904                 << MakeGroups << ", "
02905                 << ElemType << " )";
02906   }
02907   return aGroups;
02908 }
02909 
02910 
02911 //=======================================================================
02912 //function : ExtrusionAlongPathX
02913 //purpose  :
02914 //=======================================================================
02915 SMESH::ListOfGroups* SMESH_MeshEditor_i::
02916 ExtrusionAlongPathX(const SMESH::long_array&   IDsOfElements,
02917                     SMESH::SMESH_IDSource_ptr  Path,
02918                     CORBA::Long                NodeStart,
02919                     CORBA::Boolean             HasAngles,
02920                     const SMESH::double_array& Angles,
02921                     CORBA::Boolean             LinearVariation,
02922                     CORBA::Boolean             HasRefPoint,
02923                     const SMESH::PointStruct&  RefPoint,
02924                     CORBA::Boolean             MakeGroups,
02925                     SMESH::ElementType         ElemType,
02926                     SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
02927 {
02928   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
02929 
02930   SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
02931                                                       Path,
02932                                                       NodeStart,
02933                                                       HasAngles,
02934                                                       Angles,
02935                                                       LinearVariation,
02936                                                       HasRefPoint,
02937                                                       RefPoint,
02938                                                       MakeGroups,
02939                                                       (SMDSAbs_ElementType)ElemType,
02940                                                       Error);
02941 
02942   if (!myPreviewMode) {
02943     bool isDumpGroups = aGroups && aGroups->length() > 0;
02944     if (isDumpGroups)
02945       aPythonDump << "(" << *aGroups << ", error)";
02946     else
02947       aPythonDump <<"error";
02948 
02949     aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
02950                 << IDsOfElements   << ", "
02951                 << Path            << ", "
02952                 << NodeStart       << ", "
02953                 << HasAngles       << ", "
02954                 << TVar( Angles )  << ", "
02955                 << LinearVariation << ", "
02956                 << HasRefPoint     << ", "
02957                 << "SMESH.PointStruct( "
02958                 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
02959                 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
02960                 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
02961                 << MakeGroups << ", "
02962                 << ElemType << " )";
02963   }
02964   return aGroups;
02965 }
02966 
02967 
02968 //================================================================================
02977 //================================================================================
02978 
02979 SMESH::double_array*
02980 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr       thePathMesh,
02981                                           GEOM::GEOM_Object_ptr       thePathShape,
02982                                           const SMESH::double_array & theAngles)
02983 {
02984   SMESH::double_array_var aResult = new SMESH::double_array();
02985   int nbAngles = theAngles.length();
02986   if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
02987   {
02988     SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
02989     TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
02990     SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
02991     if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
02992       return aResult._retn();
02993     int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
02994     if ( nbSteps == nbAngles )
02995     {
02996       aResult.inout() = theAngles;
02997     }
02998     else
02999     {
03000       aResult->length( nbSteps );
03001       double rAn2St = double( nbAngles ) / double( nbSteps );
03002       double angPrev = 0, angle;
03003       for ( int iSt = 0; iSt < nbSteps; ++iSt )
03004       {
03005         double angCur = rAn2St * ( iSt+1 );
03006         double angCurFloor  = floor( angCur );
03007         double angPrevFloor = floor( angPrev );
03008         if ( angPrevFloor == angCurFloor )
03009           angle = rAn2St * theAngles[ int( angCurFloor ) ];
03010         else
03011         {
03012           int iP = int( angPrevFloor );
03013           double angPrevCeil = ceil(angPrev);
03014           angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
03015 
03016           int iC = int( angCurFloor );
03017           if ( iC < nbAngles )
03018             angle += ( angCur - angCurFloor ) * theAngles[ iC ];
03019 
03020           iP = int( angPrevCeil );
03021           while ( iC-- > iP )
03022             angle += theAngles[ iC ];
03023         }
03024         aResult[ iSt ] = angle;
03025         angPrev = angCur;
03026       }
03027     }
03028   }
03029   // Update Python script
03030   TPythonDump() << "rotAngles = " << theAngles;
03031   TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
03032                 << thePathMesh  << ", "
03033                 << thePathShape << ", "
03034                 << "rotAngles )";
03035 
03036   return aResult._retn();
03037 }
03038 
03039 
03040 //=======================================================================
03041 //function : mirror
03042 //purpose  :
03043 //=======================================================================
03044 
03045 SMESH::ListOfGroups*
03046 SMESH_MeshEditor_i::mirror(TIDSortedElemSet &                  theElements,
03047                            const SMESH::AxisStruct &           theAxis,
03048                            SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
03049                            CORBA::Boolean                      theCopy,
03050                            bool                                theMakeGroups,
03051                            ::SMESH_Mesh*                       theTargetMesh)
03052 {
03053   initData();
03054 
03055   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
03056   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
03057 
03058   if ( theTargetMesh )
03059     theCopy = false;
03060 
03061   gp_Trsf aTrsf;
03062   switch ( theMirrorType ) {
03063   case  SMESH::SMESH_MeshEditor::POINT:
03064     aTrsf.SetMirror( P );
03065     break;
03066   case  SMESH::SMESH_MeshEditor::AXIS:
03067     aTrsf.SetMirror( gp_Ax1( P, V ));
03068     break;
03069   default:
03070     aTrsf.SetMirror( gp_Ax2( P, V ));
03071   }
03072 
03073   TIDSortedElemSet  copyElements;
03074   TPreviewMesh      tmpMesh;
03075   TIDSortedElemSet* workElements = & theElements;
03076   SMESH_Mesh*       mesh = myMesh;
03077 
03078   if ( myPreviewMode )
03079   {
03080     tmpMesh.Copy( theElements, copyElements);
03081     if ( !theCopy && !theTargetMesh )
03082     {
03083       TIDSortedElemSet elemsAround, elemsAroundCopy;
03084       getElementsAround( theElements, GetMeshDS(), elemsAround );
03085       tmpMesh.Copy( elemsAround, elemsAroundCopy);
03086     }
03087     mesh = &tmpMesh;
03088     workElements = & copyElements;
03089     theMakeGroups = false;
03090   }
03091 
03092   ::SMESH_MeshEditor anEditor( mesh );
03093   ::SMESH_MeshEditor::PGroupIDs groupIds =
03094       anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
03095 
03096   if(theCopy || myPreviewMode)
03097     storeResult(anEditor); // store preview data or new elements
03098 
03099   if ( !myPreviewMode )
03100   {
03101     if ( theTargetMesh )
03102     {
03103       theTargetMesh->GetMeshDS()->Modified();
03104     }
03105     else
03106     {
03107       myMesh->GetMeshDS()->Modified();
03108       myMesh->SetIsModified( true );
03109     }
03110   }
03111   return theMakeGroups ? getGroups(groupIds.get()) : 0;
03112 }
03113 
03114 //=======================================================================
03115 //function : Mirror
03116 //purpose  :
03117 //=======================================================================
03118 
03119 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array &           theIDsOfElements,
03120                                 const SMESH::AxisStruct &           theAxis,
03121                                 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
03122                                 CORBA::Boolean                      theCopy)
03123 {
03124   if ( !myPreviewMode ) {
03125     TPythonDump() << this << ".Mirror( "
03126                   << theIDsOfElements              << ", "
03127                   << theAxis                       << ", "
03128                   << mirrorTypeName(theMirrorType) << ", "
03129                   << theCopy                       << " )";
03130   }
03131   if ( theIDsOfElements.length() > 0 )
03132   {
03133     TIDSortedElemSet elements;
03134     arrayToSet(theIDsOfElements, GetMeshDS(), elements);
03135     mirror(elements, theAxis, theMirrorType, theCopy, false);
03136   }
03137 }
03138 
03139 
03140 //=======================================================================
03141 //function : MirrorObject
03142 //purpose  :
03143 //=======================================================================
03144 
03145 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr           theObject,
03146                                       const SMESH::AxisStruct &           theAxis,
03147                                       SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
03148                                       CORBA::Boolean                      theCopy)
03149 {
03150   if ( !myPreviewMode ) {
03151     TPythonDump() << this << ".MirrorObject( "
03152                   << theObject                     << ", "
03153                   << theAxis                       << ", "
03154                   << mirrorTypeName(theMirrorType) << ", "
03155                   << theCopy                       << " )";
03156   }
03157   TIDSortedElemSet elements;
03158 
03159   bool emptyIfIsMesh = myPreviewMode ? false : true;
03160 
03161   if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
03162     mirror(elements, theAxis, theMirrorType, theCopy, false);
03163 }
03164 
03165 //=======================================================================
03166 //function : MirrorMakeGroups
03167 //purpose  :
03168 //=======================================================================
03169 
03170 SMESH::ListOfGroups*
03171 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array&            theIDsOfElements,
03172                                      const SMESH::AxisStruct&            theMirror,
03173                                      SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
03174 {
03175   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
03176 
03177   SMESH::ListOfGroups * aGroups = 0;
03178   if ( theIDsOfElements.length() > 0 )
03179   {
03180     TIDSortedElemSet elements;
03181     arrayToSet(theIDsOfElements, GetMeshDS(), elements);
03182     aGroups = mirror(elements, theMirror, theMirrorType, true, true);
03183   }
03184   if (!myPreviewMode) {
03185     DumpGroupsList(aPythonDump, aGroups);
03186     aPythonDump << this << ".MirrorMakeGroups( "
03187                 << theIDsOfElements              << ", "
03188                 << theMirror                     << ", "
03189                 << mirrorTypeName(theMirrorType) << " )";
03190   }
03191   return aGroups;
03192 }
03193 
03194 //=======================================================================
03195 //function : MirrorObjectMakeGroups
03196 //purpose  :
03197 //=======================================================================
03198 
03199 SMESH::ListOfGroups*
03200 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr           theObject,
03201                                            const SMESH::AxisStruct&            theMirror,
03202                                            SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
03203 {
03204   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
03205 
03206   SMESH::ListOfGroups * aGroups = 0;
03207   TIDSortedElemSet elements;
03208   if ( idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
03209     aGroups = mirror(elements, theMirror, theMirrorType, true, true);
03210 
03211   if (!myPreviewMode)
03212   {
03213     DumpGroupsList(aPythonDump,aGroups);
03214     aPythonDump << this << ".MirrorObjectMakeGroups( "
03215                 << theObject                     << ", "
03216                 << theMirror                     << ", "
03217                 << mirrorTypeName(theMirrorType) << " )";
03218   }
03219   return aGroups;
03220 }
03221 
03222 //=======================================================================
03223 //function : MirrorMakeMesh
03224 //purpose  :
03225 //=======================================================================
03226 
03227 SMESH::SMESH_Mesh_ptr
03228 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array&            theIDsOfElements,
03229                                    const SMESH::AxisStruct&            theMirror,
03230                                    SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
03231                                    CORBA::Boolean                      theCopyGroups,
03232                                    const char*                         theMeshName)
03233 {
03234   SMESH_Mesh_i* mesh_i;
03235   SMESH::SMESH_Mesh_var mesh;
03236   { // open new scope to dump "MakeMesh" command
03237     // and then "GetGroups" using SMESH_Mesh::GetGroups()
03238 
03239     TPythonDump pydump; // to prevent dump at mesh creation
03240 
03241     mesh = makeMesh( theMeshName );
03242     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
03243     if (mesh_i && theIDsOfElements.length() > 0 )
03244     {
03245       TIDSortedElemSet elements;
03246       arrayToSet(theIDsOfElements, GetMeshDS(), elements);
03247       mirror(elements, theMirror, theMirrorType,
03248              false, theCopyGroups, & mesh_i->GetImpl());
03249       mesh_i->CreateGroupServants();
03250     }
03251 
03252     if (!myPreviewMode) {
03253       pydump << mesh << " = " << this << ".MirrorMakeMesh( "
03254              << theIDsOfElements              << ", "
03255              << theMirror                     << ", "
03256              << mirrorTypeName(theMirrorType) << ", "
03257              << theCopyGroups                 << ", '"
03258              << theMeshName                   << "' )";
03259     }
03260   }
03261 
03262   //dump "GetGroups"
03263   if (!myPreviewMode && mesh_i)
03264     mesh_i->GetGroups();
03265 
03266   return mesh._retn();
03267 }
03268 
03269 //=======================================================================
03270 //function : MirrorObjectMakeMesh
03271 //purpose  :
03272 //=======================================================================
03273 
03274 SMESH::SMESH_Mesh_ptr
03275 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr           theObject,
03276                                          const SMESH::AxisStruct&            theMirror,
03277                                          SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
03278                                          CORBA::Boolean                      theCopyGroups,
03279                                          const char*                         theMeshName)
03280 {
03281   SMESH_Mesh_i* mesh_i;
03282   SMESH::SMESH_Mesh_var mesh;
03283   { // open new scope to dump "MakeMesh" command
03284     // and then "GetGroups" using SMESH_Mesh::GetGroups()
03285 
03286     TPythonDump pydump; // to prevent dump at mesh creation
03287 
03288     mesh = makeMesh( theMeshName );
03289     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
03290     TIDSortedElemSet elements;
03291     if ( mesh_i &&
03292          idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
03293     {
03294       mirror(elements, theMirror, theMirrorType,
03295              false, theCopyGroups, & mesh_i->GetImpl());
03296       mesh_i->CreateGroupServants();
03297     }
03298     if (!myPreviewMode) {
03299       pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
03300              << theObject                     << ", "
03301              << theMirror                     << ", "
03302              << mirrorTypeName(theMirrorType) << ", "
03303              << theCopyGroups                 << ", '"
03304              << theMeshName                   << "' )";
03305     }
03306   }
03307 
03308   //dump "GetGroups"
03309   if (!myPreviewMode && mesh_i)
03310     mesh_i->GetGroups();
03311 
03312   return mesh._retn();
03313 }
03314 
03315 //=======================================================================
03316 //function : translate
03317 //purpose  :
03318 //=======================================================================
03319 
03320 SMESH::ListOfGroups*
03321 SMESH_MeshEditor_i::translate(TIDSortedElemSet        & theElements,
03322                               const SMESH::DirStruct &  theVector,
03323                               CORBA::Boolean            theCopy,
03324                               bool                      theMakeGroups,
03325                               ::SMESH_Mesh*             theTargetMesh)
03326 {
03327   initData();
03328 
03329   if ( theTargetMesh )
03330     theCopy = false;
03331 
03332   gp_Trsf aTrsf;
03333   const SMESH::PointStruct * P = &theVector.PS;
03334   aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
03335 
03336   TIDSortedElemSet  copyElements;
03337   TIDSortedElemSet* workElements = &theElements;
03338   TPreviewMesh      tmpMesh;
03339   SMESH_Mesh*       mesh = myMesh;
03340 
03341   if ( myPreviewMode )
03342   {
03343     tmpMesh.Copy( theElements, copyElements);
03344     if ( !theCopy && !theTargetMesh )
03345     {
03346       TIDSortedElemSet elemsAround, elemsAroundCopy;
03347       getElementsAround( theElements, GetMeshDS(), elemsAround );
03348       tmpMesh.Copy( elemsAround, elemsAroundCopy);
03349     }
03350     mesh = &tmpMesh;
03351     workElements = & copyElements;
03352     theMakeGroups = false;
03353   }
03354 
03355   ::SMESH_MeshEditor anEditor( mesh );
03356   ::SMESH_MeshEditor::PGroupIDs groupIds =
03357       anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
03358 
03359   if(theCopy || myPreviewMode)
03360     storeResult(anEditor);
03361 
03362   if ( !myPreviewMode )
03363   {
03364     if ( theTargetMesh )
03365     {
03366       theTargetMesh->GetMeshDS()->Modified();
03367     }
03368     else
03369     {
03370       myMesh->GetMeshDS()->Modified();
03371       myMesh->SetIsModified( true );
03372     }
03373   }
03374 
03375   return theMakeGroups ? getGroups(groupIds.get()) : 0;
03376 }
03377 
03378 //=======================================================================
03379 //function : Translate
03380 //purpose  :
03381 //=======================================================================
03382 
03383 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
03384                                    const SMESH::DirStruct &  theVector,
03385                                    CORBA::Boolean            theCopy)
03386 {
03387   if (!myPreviewMode) {
03388     TPythonDump() << this << ".Translate( "
03389                   << theIDsOfElements << ", "
03390                   << theVector        << ", "
03391                   << theCopy          << " )";
03392   }
03393   if (theIDsOfElements.length()) {
03394     TIDSortedElemSet elements;
03395     arrayToSet(theIDsOfElements, GetMeshDS(), elements);
03396     translate(elements, theVector, theCopy, false);
03397   }
03398 }
03399 
03400 //=======================================================================
03401 //function : TranslateObject
03402 //purpose  :
03403 //=======================================================================
03404 
03405 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
03406                                          const SMESH::DirStruct &  theVector,
03407                                          CORBA::Boolean            theCopy)
03408 {
03409   if (!myPreviewMode) {
03410     TPythonDump() << this << ".TranslateObject( "
03411                   << theObject << ", "
03412                   << theVector << ", "
03413                   << theCopy   << " )";
03414   }
03415   TIDSortedElemSet elements;
03416 
03417   bool emptyIfIsMesh = myPreviewMode ? false : true;
03418   
03419   if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
03420     translate(elements, theVector, theCopy, false);
03421 }
03422 
03423 //=======================================================================
03424 //function : TranslateMakeGroups
03425 //purpose  :
03426 //=======================================================================
03427 
03428 SMESH::ListOfGroups*
03429 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
03430                                         const SMESH::DirStruct&  theVector)
03431 {
03432   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
03433 
03434   SMESH::ListOfGroups * aGroups = 0;
03435   if (theIDsOfElements.length()) {
03436     TIDSortedElemSet elements;
03437     arrayToSet(theIDsOfElements, GetMeshDS(), elements);
03438     aGroups = translate(elements,theVector,true,true);
03439   }
03440   if (!myPreviewMode) {
03441     DumpGroupsList(aPythonDump, aGroups);
03442     aPythonDump << this << ".TranslateMakeGroups( "
03443                 << theIDsOfElements << ", "
03444                 << theVector        << " )";
03445   }
03446   return aGroups;
03447 }
03448 
03449 //=======================================================================
03450 //function : TranslateObjectMakeGroups
03451 //purpose  :
03452 //=======================================================================
03453 
03454 SMESH::ListOfGroups*
03455 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
03456                                               const SMESH::DirStruct&   theVector)
03457 {
03458   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
03459 
03460   SMESH::ListOfGroups * aGroups = 0;
03461   TIDSortedElemSet elements;
03462   if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
03463     aGroups = translate(elements, theVector, true, true);
03464 
03465   if (!myPreviewMode) {
03466     DumpGroupsList(aPythonDump, aGroups);
03467     aPythonDump << this << ".TranslateObjectMakeGroups( "
03468                 << theObject << ", "
03469                 << theVector << " )";
03470   }
03471   return aGroups;
03472 }
03473 
03474 //=======================================================================
03475 //function : TranslateMakeMesh
03476 //purpose  :
03477 //=======================================================================
03478 
03479 SMESH::SMESH_Mesh_ptr
03480 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
03481                                       const SMESH::DirStruct&  theVector,
03482                                       CORBA::Boolean           theCopyGroups,
03483                                       const char*              theMeshName)
03484 {
03485   SMESH_Mesh_i* mesh_i;
03486   SMESH::SMESH_Mesh_var mesh;
03487 
03488   { // open new scope to dump "MakeMesh" command
03489     // and then "GetGroups" using SMESH_Mesh::GetGroups()
03490 
03491     TPythonDump pydump; // to prevent dump at mesh creation
03492 
03493     mesh = makeMesh( theMeshName );
03494     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
03495 
03496     if ( mesh_i && theIDsOfElements.length() )
03497     {
03498       TIDSortedElemSet elements;
03499       arrayToSet(theIDsOfElements, GetMeshDS(), elements);
03500       translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
03501       mesh_i->CreateGroupServants();
03502     }
03503 
03504     if ( !myPreviewMode ) {
03505       pydump << mesh << " = " << this << ".TranslateMakeMesh( "
03506              << theIDsOfElements << ", "
03507              << theVector        << ", "
03508              << theCopyGroups    << ", '"
03509              << theMeshName      << "' )";
03510     }
03511   }
03512 
03513   //dump "GetGroups"
03514   if (!myPreviewMode && mesh_i)
03515     mesh_i->GetGroups();
03516 
03517   return mesh._retn();
03518 }
03519 
03520 //=======================================================================
03521 //function : TranslateObjectMakeMesh
03522 //purpose  :
03523 //=======================================================================
03524 
03525 SMESH::SMESH_Mesh_ptr
03526 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
03527                                             const SMESH::DirStruct&   theVector,
03528                                             CORBA::Boolean            theCopyGroups,
03529                                             const char*               theMeshName)
03530 {
03531   SMESH_Mesh_i* mesh_i;
03532   SMESH::SMESH_Mesh_var mesh;
03533   { // open new scope to dump "MakeMesh" command
03534     // and then "GetGroups" using SMESH_Mesh::GetGroups()
03535 
03536     TPythonDump pydump; // to prevent dump at mesh creation
03537     mesh = makeMesh( theMeshName );
03538     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
03539 
03540     TIDSortedElemSet elements;
03541     if ( mesh_i &&
03542       idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
03543     {
03544       translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
03545       mesh_i->CreateGroupServants();
03546     }
03547     if ( !myPreviewMode ) {
03548       pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
03549              << theObject     << ", "
03550              << theVector     << ", "
03551              << theCopyGroups << ", '"
03552              << theMeshName   << "' )";
03553     }
03554   }
03555 
03556   // dump "GetGroups"
03557   if (!myPreviewMode && mesh_i)
03558     mesh_i->GetGroups();
03559 
03560   return mesh._retn();
03561 }
03562 
03563 //=======================================================================
03564 //function : rotate
03565 //purpose  :
03566 //=======================================================================
03567 
03568 SMESH::ListOfGroups*
03569 SMESH_MeshEditor_i::rotate(TIDSortedElemSet &        theElements,
03570                            const SMESH::AxisStruct & theAxis,
03571                            CORBA::Double             theAngle,
03572                            CORBA::Boolean            theCopy,
03573                            bool                      theMakeGroups,
03574                            ::SMESH_Mesh*             theTargetMesh)
03575 {
03576   initData();
03577 
03578   if ( theTargetMesh )
03579     theCopy = false;
03580 
03581   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
03582   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
03583 
03584   gp_Trsf aTrsf;
03585   aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
03586 
03587   TIDSortedElemSet  copyElements;
03588   TIDSortedElemSet* workElements = &theElements;
03589   TPreviewMesh      tmpMesh;
03590   SMESH_Mesh*       mesh = myMesh;
03591 
03592   if ( myPreviewMode ) {
03593     tmpMesh.Copy( theElements, copyElements );
03594     if ( !theCopy && !theTargetMesh )
03595     {
03596       TIDSortedElemSet elemsAround, elemsAroundCopy;
03597       getElementsAround( theElements, GetMeshDS(), elemsAround );
03598       tmpMesh.Copy( elemsAround, elemsAroundCopy);
03599     }
03600     mesh = &tmpMesh;
03601     workElements = &copyElements;
03602     theMakeGroups = false;
03603   }
03604 
03605   ::SMESH_MeshEditor anEditor( mesh );
03606   ::SMESH_MeshEditor::PGroupIDs groupIds =
03607       anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
03608 
03609   if(theCopy || myPreviewMode)
03610     storeResult(anEditor);
03611 
03612   if ( !myPreviewMode )
03613   {
03614     if ( theTargetMesh )
03615     {
03616       theTargetMesh->GetMeshDS()->Modified();
03617     }
03618     else
03619     {
03620       myMesh->GetMeshDS()->Modified();
03621       myMesh->SetIsModified( true );
03622     }
03623   }
03624 
03625   return theMakeGroups ? getGroups(groupIds.get()) : 0;
03626 }
03627 
03628 //=======================================================================
03629 //function : Rotate
03630 //purpose  :
03631 //=======================================================================
03632 
03633 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
03634                                 const SMESH::AxisStruct & theAxis,
03635                                 CORBA::Double             theAngle,
03636                                 CORBA::Boolean            theCopy)
03637 {
03638   if (!myPreviewMode) {
03639     TPythonDump() << this << ".Rotate( "
03640                   << theIDsOfElements << ", "
03641                   << theAxis          << ", "
03642                   << TVar( theAngle ) << ", "
03643                   << theCopy          << " )";
03644   }
03645   if (theIDsOfElements.length() > 0)
03646   {
03647     TIDSortedElemSet elements;
03648     arrayToSet(theIDsOfElements, GetMeshDS(), elements);
03649     rotate(elements,theAxis,theAngle,theCopy,false);
03650   }
03651 }
03652 
03653 //=======================================================================
03654 //function : RotateObject
03655 //purpose  :
03656 //=======================================================================
03657 
03658 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
03659                                       const SMESH::AxisStruct & theAxis,
03660                                       CORBA::Double             theAngle,
03661                                       CORBA::Boolean            theCopy)
03662 {
03663   if ( !myPreviewMode ) {
03664     TPythonDump() << this << ".RotateObject( "
03665                   << theObject        << ", "
03666                   << theAxis          << ", "
03667                   << TVar( theAngle ) << ", "
03668                   << theCopy          << " )";
03669   }
03670   TIDSortedElemSet elements;
03671   bool emptyIfIsMesh = myPreviewMode ? false : true;
03672   if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
03673     rotate(elements,theAxis,theAngle,theCopy,false);
03674 }
03675 
03676 //=======================================================================
03677 //function : RotateMakeGroups
03678 //purpose  :
03679 //=======================================================================
03680 
03681 SMESH::ListOfGroups*
03682 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
03683                                      const SMESH::AxisStruct& theAxis,
03684                                      CORBA::Double            theAngle)
03685 {
03686   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
03687 
03688   SMESH::ListOfGroups * aGroups = 0;
03689   if (theIDsOfElements.length() > 0)
03690   {
03691     TIDSortedElemSet elements;
03692     arrayToSet(theIDsOfElements, GetMeshDS(), elements);
03693     aGroups = rotate(elements,theAxis,theAngle,true,true);
03694   }
03695   if (!myPreviewMode) {
03696     DumpGroupsList(aPythonDump, aGroups);
03697     aPythonDump << this << ".RotateMakeGroups( "
03698                 << theIDsOfElements << ", "
03699                 << theAxis          << ", "
03700                 << TVar( theAngle ) << " )";
03701   }
03702   return aGroups;
03703 }
03704 
03705 //=======================================================================
03706 //function : RotateObjectMakeGroups
03707 //purpose  :
03708 //=======================================================================
03709 
03710 SMESH::ListOfGroups*
03711 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
03712                                            const SMESH::AxisStruct&  theAxis,
03713                                            CORBA::Double             theAngle)
03714 {
03715   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
03716 
03717   SMESH::ListOfGroups * aGroups = 0;
03718   TIDSortedElemSet elements;
03719   if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
03720     aGroups = rotate(elements, theAxis, theAngle, true, true);
03721 
03722   if (!myPreviewMode) {
03723     DumpGroupsList(aPythonDump, aGroups);
03724     aPythonDump << this << ".RotateObjectMakeGroups( "
03725                 << theObject        << ", "
03726                 << theAxis          << ", "
03727                 << TVar( theAngle ) << " )";
03728   }
03729   return aGroups;
03730 }
03731 
03732 //=======================================================================
03733 //function : RotateMakeMesh
03734 //purpose  :
03735 //=======================================================================
03736 
03737 SMESH::SMESH_Mesh_ptr
03738 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
03739                                    const SMESH::AxisStruct& theAxis,
03740                                    CORBA::Double            theAngleInRadians,
03741                                    CORBA::Boolean           theCopyGroups,
03742                                    const char*              theMeshName)
03743 {
03744   SMESH::SMESH_Mesh_var mesh;
03745   SMESH_Mesh_i* mesh_i;
03746 
03747   { // open new scope to dump "MakeMesh" command
03748     // and then "GetGroups" using SMESH_Mesh::GetGroups()
03749 
03750     TPythonDump pydump; // to prevent dump at mesh creation
03751 
03752     mesh = makeMesh( theMeshName );
03753     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
03754 
03755     if ( mesh_i && theIDsOfElements.length() > 0 )
03756     {
03757       TIDSortedElemSet elements;
03758       arrayToSet(theIDsOfElements, GetMeshDS(), elements);
03759       rotate(elements, theAxis, theAngleInRadians,
03760              false, theCopyGroups, & mesh_i->GetImpl());
03761       mesh_i->CreateGroupServants();
03762     }
03763     if ( !myPreviewMode ) {
03764       pydump << mesh << " = " << this << ".RotateMakeMesh( "
03765              << theIDsOfElements          << ", "
03766              << theAxis                   << ", "
03767              << TVar( theAngleInRadians ) << ", "
03768              << theCopyGroups             << ", '"
03769              << theMeshName               << "' )";
03770     }
03771   }
03772 
03773   // dump "GetGroups"
03774   if (!myPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
03775     mesh_i->GetGroups();
03776 
03777   return mesh._retn();
03778 }
03779 
03780 //=======================================================================
03781 //function : RotateObjectMakeMesh
03782 //purpose  :
03783 //=======================================================================
03784 
03785 SMESH::SMESH_Mesh_ptr
03786 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
03787                                          const SMESH::AxisStruct&  theAxis,
03788                                          CORBA::Double             theAngleInRadians,
03789                                          CORBA::Boolean            theCopyGroups,
03790                                          const char*               theMeshName)
03791 {
03792   SMESH::SMESH_Mesh_var mesh;
03793   SMESH_Mesh_i* mesh_i;
03794 
03795   {// open new scope to dump "MakeMesh" command
03796    // and then "GetGroups" using SMESH_Mesh::GetGroups()
03797 
03798     TPythonDump pydump; // to prevent dump at mesh creation
03799     mesh = makeMesh( theMeshName );
03800     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
03801 
03802     TIDSortedElemSet elements;
03803     if (mesh_i &&
03804         idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
03805     {
03806       rotate(elements, theAxis, theAngleInRadians,
03807              false, theCopyGroups, & mesh_i->GetImpl());
03808       mesh_i->CreateGroupServants();
03809     }
03810     if ( !myPreviewMode ) {
03811       pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
03812              << theObject                 << ", "
03813              << theAxis                   << ", "
03814              << TVar( theAngleInRadians ) << ", "
03815              << theCopyGroups             << ", '"
03816              << theMeshName               << "' )";
03817     }
03818   }
03819 
03820   // dump "GetGroups"
03821   if (!myPreviewMode && mesh_i)
03822     mesh_i->GetGroups();
03823 
03824   return mesh._retn();
03825 }
03826 
03827 //=======================================================================
03828 //function : scale
03829 //purpose  :
03830 //=======================================================================
03831 
03832 SMESH::ListOfGroups*
03833 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr  theObject,
03834                           const SMESH::PointStruct&  thePoint,
03835                           const SMESH::double_array& theScaleFact,
03836                           CORBA::Boolean             theCopy,
03837                           bool                       theMakeGroups,
03838                           ::SMESH_Mesh*              theTargetMesh)
03839 {
03840   initData();
03841   if ( theScaleFact.length() < 1 )
03842     THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
03843   if ( theScaleFact.length() == 2 )
03844     THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
03845 
03846   if ( theTargetMesh )
03847     theCopy = false;
03848 
03849   TIDSortedElemSet elements;
03850   bool emptyIfIsMesh = myPreviewMode ? false : true;
03851   if ( !idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
03852     return 0;
03853 
03854   double S[3] = {
03855     theScaleFact[0],
03856     (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
03857     (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
03858   };
03859   double tol = std::numeric_limits<double>::max();
03860   gp_Trsf aTrsf;
03861   aTrsf.SetValues( S[0], 0,    0,    thePoint.x * (1-S[0]),
03862                    0,    S[1], 0,    thePoint.y * (1-S[1]),
03863                    0,    0,    S[2], thePoint.z * (1-S[2]),   tol, tol);
03864 
03865   TIDSortedElemSet  copyElements;
03866   TPreviewMesh      tmpMesh;
03867   TIDSortedElemSet* workElements = &elements;
03868   SMESH_Mesh*       mesh = myMesh;
03869   
03870   if ( myPreviewMode )
03871   {
03872     tmpMesh.Copy( elements, copyElements);
03873     if ( !theCopy && !theTargetMesh )
03874     {
03875       TIDSortedElemSet elemsAround, elemsAroundCopy;
03876       getElementsAround( elements, GetMeshDS(), elemsAround );
03877       tmpMesh.Copy( elemsAround, elemsAroundCopy);
03878     }
03879     mesh = &tmpMesh;
03880     workElements = & copyElements;
03881     theMakeGroups = false;
03882   }
03883 
03884   ::SMESH_MeshEditor anEditor( mesh );
03885   ::SMESH_MeshEditor::PGroupIDs groupIds =
03886       anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
03887 
03888   if(theCopy || myPreviewMode )
03889     storeResult(anEditor);
03890 
03891   if ( !myPreviewMode )
03892   {
03893     if ( theTargetMesh )
03894     {
03895       theTargetMesh->GetMeshDS()->Modified();
03896     }
03897     else
03898     {
03899       myMesh->GetMeshDS()->Modified();
03900       myMesh->SetIsModified( true );
03901     }
03902   }
03903 
03904   return theMakeGroups ? getGroups(groupIds.get()) : 0;
03905 }
03906 
03907 //=======================================================================
03908 //function : Scale
03909 //purpose  :
03910 //=======================================================================
03911 
03912 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr  theObject,
03913                                const SMESH::PointStruct&  thePoint,
03914                                const SMESH::double_array& theScaleFact,
03915                                CORBA::Boolean             theCopy)
03916 {
03917   if ( !myPreviewMode ) {
03918     TPythonDump() << this << ".Scale( "
03919                   << theObject            << ", "
03920                   << thePoint             << ", "
03921                   << TVar( theScaleFact ) << ", "
03922                   << theCopy              << " )";
03923   }
03924   scale(theObject, thePoint, theScaleFact, theCopy, false);
03925 }
03926 
03927 
03928 //=======================================================================
03929 //function : ScaleMakeGroups
03930 //purpose  :
03931 //=======================================================================
03932 
03933 SMESH::ListOfGroups*
03934 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
03935                                     const SMESH::PointStruct&  thePoint,
03936                                     const SMESH::double_array& theScaleFact)
03937 {
03938   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
03939 
03940   SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
03941   if (!myPreviewMode) {
03942     DumpGroupsList(aPythonDump, aGroups);
03943     aPythonDump << this << ".Scale("
03944                 << theObject            << ","
03945                 << thePoint             << ","
03946                 << TVar( theScaleFact ) << ",True,True)";
03947   }
03948   return aGroups;
03949 }
03950 
03951 
03952 //=======================================================================
03953 //function : ScaleMakeMesh
03954 //purpose  :
03955 //=======================================================================
03956 
03957 SMESH::SMESH_Mesh_ptr
03958 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr  theObject,
03959                                   const SMESH::PointStruct&  thePoint,
03960                                   const SMESH::double_array& theScaleFact,
03961                                   CORBA::Boolean             theCopyGroups,
03962                                   const char*                theMeshName)
03963 {
03964   SMESH_Mesh_i* mesh_i;
03965   SMESH::SMESH_Mesh_var mesh;
03966   { // open new scope to dump "MakeMesh" command
03967     // and then "GetGroups" using SMESH_Mesh::GetGroups()
03968 
03969     TPythonDump pydump; // to prevent dump at mesh creation
03970     mesh = makeMesh( theMeshName );
03971     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
03972 
03973     if ( mesh_i )
03974     {
03975       scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
03976       mesh_i->CreateGroupServants();
03977     }
03978     if ( !myPreviewMode )
03979       pydump << mesh << " = " << this << ".ScaleMakeMesh( "
03980              << theObject            << ", "
03981              << thePoint             << ", "
03982              << TVar( theScaleFact ) << ", "
03983              << theCopyGroups        << ", '"
03984              << theMeshName          << "' )";
03985   }
03986 
03987   // dump "GetGroups"
03988   if (!myPreviewMode && mesh_i)
03989     mesh_i->GetGroups();
03990 
03991   return mesh._retn();
03992 }
03993 
03994 
03995 //=======================================================================
03996 //function : FindCoincidentNodes
03997 //purpose  :
03998 //=======================================================================
03999 
04000 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tolerance,
04001                                               SMESH::array_of_long_array_out GroupsOfNodes)
04002 {
04003   initData();
04004 
04005   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
04006   ::SMESH_MeshEditor anEditor( myMesh );
04007   TIDSortedNodeSet nodes; // no input nodes
04008   anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
04009 
04010   GroupsOfNodes = new SMESH::array_of_long_array;
04011   GroupsOfNodes->length( aListOfListOfNodes.size() );
04012   ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
04013   for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
04014     list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
04015     list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
04016     SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
04017     aGroup.length( aListOfNodes.size() );
04018     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
04019       aGroup[ j ] = (*lIt)->GetID();
04020   }
04021   TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
04022                 << Tolerance << " )";
04023 }
04024 
04025 //=======================================================================
04026 //function : FindCoincidentNodesOnPart
04027 //purpose  :
04028 //=======================================================================
04029 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr      theObject,
04030                                                    CORBA::Double                  Tolerance,
04031                                                    SMESH::array_of_long_array_out GroupsOfNodes)
04032 {
04033   initData();
04034 
04035   TIDSortedNodeSet nodes;
04036   idSourceToNodeSet( theObject, GetMeshDS(), nodes );
04037 
04038   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
04039   ::SMESH_MeshEditor anEditor( myMesh );
04040   if(!nodes.empty())
04041     anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
04042 
04043   GroupsOfNodes = new SMESH::array_of_long_array;
04044   GroupsOfNodes->length( aListOfListOfNodes.size() );
04045   ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
04046   for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
04047   {
04048     list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
04049     list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
04050     SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
04051     aGroup.length( aListOfNodes.size() );
04052     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
04053       aGroup[ j ] = (*lIt)->GetID();
04054   }
04055   TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
04056                 <<theObject<<", "
04057                 << Tolerance << " )";
04058 }
04059 
04060 //================================================================================
04065 //================================================================================
04066 
04067 void SMESH_MeshEditor_i::
04068 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr      theObject,
04069                              CORBA::Double                  theTolerance,
04070                              SMESH::array_of_long_array_out theGroupsOfNodes,
04071                              const SMESH::ListOfIDSources&  theExceptSubMeshOrGroups)
04072 {
04073   initData();
04074 
04075   TIDSortedNodeSet nodes;
04076   idSourceToNodeSet( theObject, GetMeshDS(), nodes );
04077 
04078   for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
04079   {
04080     TIDSortedNodeSet exceptNodes;
04081     idSourceToNodeSet( theExceptSubMeshOrGroups[i], GetMeshDS(), exceptNodes );
04082     TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
04083     for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
04084       nodes.erase( *avoidNode );
04085   }
04086   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
04087   ::SMESH_MeshEditor anEditor( myMesh );
04088   if(!nodes.empty())
04089     anEditor.FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
04090 
04091   theGroupsOfNodes = new SMESH::array_of_long_array;
04092   theGroupsOfNodes->length( aListOfListOfNodes.size() );
04093   ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
04094   for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
04095   {
04096     list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
04097     list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
04098     SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
04099     aGroup.length( aListOfNodes.size() );
04100     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
04101       aGroup[ j ] = (*lIt)->GetID();
04102   }
04103   TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
04104                 << theObject<<", "
04105                 << theTolerance << ", "
04106                 << theExceptSubMeshOrGroups << " )";
04107 }
04108 
04109 //=======================================================================
04110 //function : MergeNodes
04111 //purpose  :
04112 //=======================================================================
04113 
04114 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
04115 {
04116   initData();
04117 
04118   SMESHDS_Mesh* aMesh = GetMeshDS();
04119 
04120   TPythonDump aTPythonDump;
04121   aTPythonDump << this << ".MergeNodes([";
04122   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
04123   for (int i = 0; i < GroupsOfNodes.length(); i++)
04124   {
04125     const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
04126     aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
04127     list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
04128     for ( int j = 0; j < aNodeGroup.length(); j++ )
04129     {
04130       CORBA::Long index = aNodeGroup[ j ];
04131       const SMDS_MeshNode * node = aMesh->FindNode(index);
04132       if ( node )
04133         aListOfNodes.push_back( node );
04134     }
04135     if ( aListOfNodes.size() < 2 )
04136       aListOfListOfNodes.pop_back();
04137 
04138     if ( i > 0 ) aTPythonDump << ", ";
04139     aTPythonDump << aNodeGroup;
04140   }
04141   ::SMESH_MeshEditor anEditor( myMesh );
04142   anEditor.MergeNodes( aListOfListOfNodes );
04143 
04144   aTPythonDump <<  "])";
04145   myMesh->GetMeshDS()->Modified();
04146   myMesh->SetIsModified( true );
04147 }
04148 
04149 //=======================================================================
04150 //function : FindEqualElements
04151 //purpose  :
04152 //=======================================================================
04153 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr      theObject,
04154                                            SMESH::array_of_long_array_out GroupsOfElementsID)
04155 {
04156   initData();
04157 
04158   SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
04159   if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
04160   {
04161     typedef list<int> TListOfIDs;
04162     set<const SMDS_MeshElement*> elems;
04163     SMESH::long_array_var aElementsId = theObject->GetIDs();
04164     SMESHDS_Mesh* aMesh = GetMeshDS();
04165 
04166     for(int i = 0; i < aElementsId->length(); i++) {
04167       CORBA::Long anID = aElementsId[i];
04168       const SMDS_MeshElement * elem = aMesh->FindElement(anID);
04169       if (elem) {
04170         elems.insert(elem);
04171       }
04172     }
04173 
04174     ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
04175     ::SMESH_MeshEditor anEditor( myMesh );
04176     anEditor.FindEqualElements( elems, aListOfListOfElementsID );
04177 
04178     GroupsOfElementsID = new SMESH::array_of_long_array;
04179     GroupsOfElementsID->length( aListOfListOfElementsID.size() );
04180 
04181     ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin();
04182     for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) {
04183       SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
04184       TListOfIDs& listOfIDs = *arraysIt;
04185       aGroup.length( listOfIDs.size() );
04186       TListOfIDs::iterator idIt = listOfIDs.begin();
04187       for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) {
04188         aGroup[ k ] = *idIt;
04189       }
04190     }
04191 
04192     TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
04193                   <<theObject<<" )";
04194   }
04195 }
04196 
04197 //=======================================================================
04198 //function : MergeElements
04199 //purpose  :
04200 //=======================================================================
04201 
04202 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
04203 {
04204   initData();
04205 
04206   TPythonDump aTPythonDump;
04207   aTPythonDump << this << ".MergeElements( [";
04208 
04209   ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
04210 
04211   for (int i = 0; i < GroupsOfElementsID.length(); i++) {
04212     const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
04213     aListOfListOfElementsID.push_back( list< int >() );
04214     list< int >& aListOfElemsID = aListOfListOfElementsID.back();
04215     for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
04216       CORBA::Long id = anElemsIDGroup[ j ];
04217       aListOfElemsID.push_back( id );
04218     }
04219     if ( aListOfElemsID.size() < 2 )
04220       aListOfListOfElementsID.pop_back();
04221     if ( i > 0 ) aTPythonDump << ", ";
04222     aTPythonDump << anElemsIDGroup;
04223   }
04224 
04225   ::SMESH_MeshEditor anEditor( myMesh );
04226   anEditor.MergeElements(aListOfListOfElementsID);
04227   myMesh->GetMeshDS()->Modified();
04228   myMesh->SetIsModified( true );
04229 
04230   aTPythonDump << "] )";
04231 }
04232 
04233 //=======================================================================
04234 //function : MergeEqualElements
04235 //purpose  :
04236 //=======================================================================
04237 
04238 void SMESH_MeshEditor_i::MergeEqualElements()
04239 {
04240   initData();
04241 
04242   ::SMESH_MeshEditor anEditor( myMesh );
04243   anEditor.MergeEqualElements();
04244 
04245   myMesh->GetMeshDS()->Modified();
04246 
04247   TPythonDump() << this << ".MergeEqualElements()";
04248 }
04249 
04250 //=============================================================================
04254 //=============================================================================
04255 
04256 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long   NodeID,
04257                                             CORBA::Double x,
04258                                             CORBA::Double y,
04259                                             CORBA::Double z)
04260 {
04261   initData(/*deleteSearchers=*/false);
04262 
04263   const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
04264   if ( !node )
04265     return false;
04266 
04267   if ( theNodeSearcher )
04268     theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
04269 
04270   if ( myPreviewMode ) // make preview data
04271   {
04272     // in a preview mesh, make edges linked to a node
04273     TPreviewMesh tmpMesh;
04274     TIDSortedElemSet linkedNodes;
04275     ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
04276     TIDSortedElemSet::iterator nIt = linkedNodes.begin();
04277     SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
04278     for ( ; nIt != linkedNodes.end(); ++nIt )
04279     {
04280       SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
04281       tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
04282     }
04283     // move copied node
04284     if ( nodeCpy1 )
04285       tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
04286     // fill preview data
04287     ::SMESH_MeshEditor anEditor( & tmpMesh );
04288     storeResult( anEditor );
04289   }
04290   else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
04291     theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
04292   else
04293     GetMeshDS()->MoveNode(node, x, y, z);
04294 
04295   if ( !myPreviewMode )
04296   {
04297     // Update Python script
04298     TPythonDump() << "isDone = " << this << ".MoveNode( "
04299                   << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
04300     myMesh->GetMeshDS()->Modified();
04301     myMesh->SetIsModified( true );
04302   }
04303 
04304   return true;
04305 }
04306 
04307 //================================================================================
04311 //================================================================================
04312 
04313 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
04314                                                   CORBA::Double y,
04315                                                   CORBA::Double z)
04316 {
04317   theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
04318 
04319   if ( !theNodeSearcher ) {
04320     ::SMESH_MeshEditor anEditor( myMesh );
04321     theNodeSearcher = anEditor.GetNodeSearcher();
04322   }
04323   gp_Pnt p( x,y,z );
04324   if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
04325     return node->GetID();
04326 
04327   return 0;
04328 }
04329 
04330 //================================================================================
04335 //================================================================================
04336 
04337 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
04338                                                        CORBA::Double y,
04339                                                        CORBA::Double z,
04340                                                        CORBA::Long   theNodeID)
04341 {
04342   // We keep theNodeSearcher until any mesh modification:
04343   // 1) initData() deletes theNodeSearcher at any edition,
04344   // 2) TSearchersDeleter - at any mesh compute event and mesh change
04345 
04346   initData(/*deleteSearchers=*/false);
04347 
04348   theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
04349 
04350   int nodeID = theNodeID;
04351   const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
04352   if ( !node ) // preview moving node
04353   {
04354     if ( !theNodeSearcher ) {
04355       ::SMESH_MeshEditor anEditor( myMesh );
04356       theNodeSearcher = anEditor.GetNodeSearcher();
04357     }
04358     gp_Pnt p( x,y,z );
04359     node = theNodeSearcher->FindClosestTo( p );
04360   }
04361   if ( node ) {
04362     nodeID = node->GetID();
04363     if ( myPreviewMode ) // make preview data
04364     {
04365       // in a preview mesh, make edges linked to a node
04366       TPreviewMesh tmpMesh;
04367       TIDSortedElemSet linkedNodes;
04368       ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
04369       TIDSortedElemSet::iterator nIt = linkedNodes.begin();
04370       for ( ; nIt != linkedNodes.end(); ++nIt )
04371       {
04372         SMDS_LinearEdge edge( node, cast2Node( *nIt ));
04373         tmpMesh.Copy( &edge );
04374       }
04375       // move copied node
04376       node = tmpMesh.GetMeshDS()->FindNode( nodeID );
04377       if ( node )
04378         tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
04379       // fill preview data
04380       ::SMESH_MeshEditor anEditor( & tmpMesh );
04381       storeResult( anEditor );
04382     }
04383     else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
04384     {
04385       theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
04386     }
04387     else
04388     {
04389       GetMeshDS()->MoveNode(node, x, y, z);
04390     }
04391   }
04392 
04393   if ( !myPreviewMode )
04394   {
04395     TPythonDump() << "nodeID = " << this
04396                   << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
04397                   << ", " << nodeID << " )";
04398 
04399     myMesh->GetMeshDS()->Modified();
04400     myMesh->SetIsModified( true );
04401   }
04402 
04403   return nodeID;
04404 }
04405 
04406 //=======================================================================
04412 //=======================================================================
04413 
04414 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double      x,
04415                                                            CORBA::Double      y,
04416                                                            CORBA::Double      z,
04417                                                            SMESH::ElementType type)
04418 {
04419   SMESH::long_array_var res = new SMESH::long_array;
04420   vector< const SMDS_MeshElement* > foundElems;
04421 
04422   theSearchersDeleter.Set( myMesh );
04423   if ( !theElementSearcher ) {
04424     ::SMESH_MeshEditor anEditor( myMesh );
04425     theElementSearcher = anEditor.GetElementSearcher();
04426   }
04427   theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
04428                                            SMDSAbs_ElementType( type ),
04429                                            foundElems);
04430   res->length( foundElems.size() );
04431   for ( int i = 0; i < foundElems.size(); ++i )
04432     res[i] = foundElems[i]->GetID();
04433 
04434   if ( !myPreviewMode ) // call from tui
04435     TPythonDump() << "res = " << this << ".FindElementsByPoint( "
04436                   << x << ", "
04437                   << y << ", "
04438                   << z << ", "
04439                   << type << " )";
04440 
04441   return res._retn();
04442 }
04443 
04444 //=======================================================================
04445 //function : FindAmongElementsByPoint
04446 //purpose  : Searching among the given elements, return elements of given type 
04447 //           where the given point is IN or ON.
04448 //           'ALL' type means elements of any type excluding nodes
04449 //=======================================================================
04450 
04451 SMESH::long_array*
04452 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
04453                                              CORBA::Double             x,
04454                                              CORBA::Double             y,
04455                                              CORBA::Double             z,
04456                                              SMESH::ElementType        type)
04457 {
04458   SMESH::long_array_var res = new SMESH::long_array;
04459   
04460   SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
04461   if ( types->length() == 1 && // a part contains only nodes or 0D elements
04462        ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D ) &&
04463        type != types[0] ) // but search of elements of dim > 0
04464     return res._retn();
04465 
04466   if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh 
04467     return FindElementsByPoint( x,y,z, type );
04468 
04469   string partIOR = SMESH_Gen_i::GetORB()->object_to_string( elementIDs );
04470   if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( elementIDs ))
04471     // take into account passible group modification
04472     partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
04473   partIOR += SMESH_Comment( type );
04474 
04475   TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
04476 
04477   theSearchersDeleter.Set( myMesh, partIOR );
04478   if ( !theElementSearcher )
04479   {
04480     // create a searcher from elementIDs
04481     SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
04482     SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
04483 
04484     if ( !idSourceToSet( elementIDs, meshDS, elements,
04485                          SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
04486       return res._retn();
04487 
04488     typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
04489     SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
04490 
04491     ::SMESH_MeshEditor anEditor( myMesh );
04492     theElementSearcher = anEditor.GetElementSearcher(elemsIt);
04493   }
04494 
04495   vector< const SMDS_MeshElement* > foundElems;
04496 
04497   theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
04498                                            SMDSAbs_ElementType( type ),
04499                                            foundElems);
04500   res->length( foundElems.size() );
04501   for ( int i = 0; i < foundElems.size(); ++i )
04502     res[i] = foundElems[i]->GetID();
04503 
04504   if ( !myPreviewMode ) // call from tui
04505     TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
04506                   << elementIDs << ", "
04507                   << x << ", "
04508                   << y << ", "
04509                   << z << ", "
04510                   << type << " )";
04511 
04512   return res._retn();
04513   
04514 }
04515 //=======================================================================
04516 //function : GetPointState
04517 //purpose  : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
04518 //           TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
04519 //=======================================================================
04520 
04521 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
04522                                                CORBA::Double y,
04523                                                CORBA::Double z)
04524 {
04525   theSearchersDeleter.Set( myMesh );
04526   if ( !theElementSearcher ) {
04527     ::SMESH_MeshEditor anEditor( myMesh );
04528     theElementSearcher = anEditor.GetElementSearcher();
04529   }
04530   return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
04531 }
04532 
04533 //=======================================================================
04534 //function : convError
04535 //purpose  :
04536 //=======================================================================
04537 
04538 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
04539 
04540 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
04541 {
04542   switch ( e ) {
04543     RETCASE( SEW_OK );
04544     RETCASE( SEW_BORDER1_NOT_FOUND );
04545     RETCASE( SEW_BORDER2_NOT_FOUND );
04546     RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
04547     RETCASE( SEW_BAD_SIDE_NODES );
04548     RETCASE( SEW_VOLUMES_TO_SPLIT );
04549     RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
04550     RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
04551     RETCASE( SEW_BAD_SIDE1_NODES );
04552     RETCASE( SEW_BAD_SIDE2_NODES );
04553   }
04554   return SMESH::SMESH_MeshEditor::SEW_OK;
04555 }
04556 
04557 //=======================================================================
04558 //function : SewFreeBorders
04559 //purpose  :
04560 //=======================================================================
04561 
04562 SMESH::SMESH_MeshEditor::Sew_Error
04563 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
04564                                    CORBA::Long SecondNodeID1,
04565                                    CORBA::Long LastNodeID1,
04566                                    CORBA::Long FirstNodeID2,
04567                                    CORBA::Long SecondNodeID2,
04568                                    CORBA::Long LastNodeID2,
04569                                    CORBA::Boolean CreatePolygons,
04570                                    CORBA::Boolean CreatePolyedrs)
04571 {
04572   initData();
04573 
04574   SMESHDS_Mesh* aMesh = GetMeshDS();
04575 
04576   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
04577   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
04578   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
04579   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
04580   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
04581   const SMDS_MeshNode* aSide2ThirdNode   = aMesh->FindNode( LastNodeID2   );
04582 
04583   if (!aBorderFirstNode ||
04584       !aBorderSecondNode||
04585       !aBorderLastNode)
04586     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
04587   if (!aSide2FirstNode  ||
04588       !aSide2SecondNode ||
04589       !aSide2ThirdNode)
04590     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
04591 
04592   TPythonDump() << "error = " << this << ".SewFreeBorders( "
04593                 << FirstNodeID1  << ", "
04594                 << SecondNodeID1 << ", "
04595                 << LastNodeID1   << ", "
04596                 << FirstNodeID2  << ", "
04597                 << SecondNodeID2 << ", "
04598                 << LastNodeID2   << ", "
04599                 << CreatePolygons<< ", "
04600                 << CreatePolyedrs<< " )";
04601 
04602   ::SMESH_MeshEditor anEditor( myMesh );
04603   SMESH::SMESH_MeshEditor::Sew_Error error =
04604     convError( anEditor.SewFreeBorder (aBorderFirstNode,
04605                                        aBorderSecondNode,
04606                                        aBorderLastNode,
04607                                        aSide2FirstNode,
04608                                        aSide2SecondNode,
04609                                        aSide2ThirdNode,
04610                                        true,
04611                                        CreatePolygons,
04612                                        CreatePolyedrs) );
04613 
04614   storeResult(anEditor);
04615 
04616   myMesh->GetMeshDS()->Modified();
04617   myMesh->SetIsModified( true );
04618 
04619   return error;
04620 }
04621 
04622 
04623 //=======================================================================
04624 //function : SewConformFreeBorders
04625 //purpose  :
04626 //=======================================================================
04627 
04628 SMESH::SMESH_MeshEditor::Sew_Error
04629 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
04630                                           CORBA::Long SecondNodeID1,
04631                                           CORBA::Long LastNodeID1,
04632                                           CORBA::Long FirstNodeID2,
04633                                           CORBA::Long SecondNodeID2)
04634 {
04635   initData();
04636 
04637   SMESHDS_Mesh* aMesh = GetMeshDS();
04638 
04639   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
04640   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
04641   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
04642   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
04643   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
04644   const SMDS_MeshNode* aSide2ThirdNode   = 0;
04645 
04646   if (!aBorderFirstNode ||
04647       !aBorderSecondNode||
04648       !aBorderLastNode )
04649     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
04650   if (!aSide2FirstNode  ||
04651       !aSide2SecondNode)
04652     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
04653 
04654   TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
04655                 << FirstNodeID1  << ", "
04656                 << SecondNodeID1 << ", "
04657                 << LastNodeID1   << ", "
04658                 << FirstNodeID2  << ", "
04659                 << SecondNodeID2 << " )";
04660 
04661   ::SMESH_MeshEditor anEditor( myMesh );
04662   SMESH::SMESH_MeshEditor::Sew_Error error =
04663     convError( anEditor.SewFreeBorder (aBorderFirstNode,
04664                                        aBorderSecondNode,
04665                                        aBorderLastNode,
04666                                        aSide2FirstNode,
04667                                        aSide2SecondNode,
04668                                        aSide2ThirdNode,
04669                                        true,
04670                                        false, false) );
04671 
04672   storeResult(anEditor);
04673 
04674   myMesh->GetMeshDS()->Modified();
04675   myMesh->SetIsModified( true );
04676 
04677   return error;
04678 }
04679 
04680 
04681 //=======================================================================
04682 //function : SewBorderToSide
04683 //purpose  :
04684 //=======================================================================
04685 
04686 SMESH::SMESH_MeshEditor::Sew_Error
04687 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
04688                                     CORBA::Long SecondNodeIDOnFreeBorder,
04689                                     CORBA::Long LastNodeIDOnFreeBorder,
04690                                     CORBA::Long FirstNodeIDOnSide,
04691                                     CORBA::Long LastNodeIDOnSide,
04692                                     CORBA::Boolean CreatePolygons,
04693                                     CORBA::Boolean CreatePolyedrs)
04694 {
04695   initData();
04696 
04697   SMESHDS_Mesh* aMesh = GetMeshDS();
04698 
04699   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeIDOnFreeBorder  );
04700   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
04701   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeIDOnFreeBorder   );
04702   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeIDOnSide  );
04703   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( LastNodeIDOnSide );
04704   const SMDS_MeshNode* aSide2ThirdNode   = 0;
04705 
04706   if (!aBorderFirstNode ||
04707       !aBorderSecondNode||
04708       !aBorderLastNode  )
04709     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
04710   if (!aSide2FirstNode  ||
04711       !aSide2SecondNode)
04712     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
04713 
04714   TPythonDump() << "error = " << this << ".SewBorderToSide( "
04715                 << FirstNodeIDOnFreeBorder  << ", "
04716                 << SecondNodeIDOnFreeBorder << ", "
04717                 << LastNodeIDOnFreeBorder   << ", "
04718                 << FirstNodeIDOnSide        << ", "
04719                 << LastNodeIDOnSide         << ", "
04720                 << CreatePolygons           << ", "
04721                 << CreatePolyedrs           << ") ";
04722 
04723   ::SMESH_MeshEditor anEditor( myMesh );
04724   SMESH::SMESH_MeshEditor::Sew_Error error =
04725     convError( anEditor.SewFreeBorder (aBorderFirstNode,
04726                                        aBorderSecondNode,
04727                                        aBorderLastNode,
04728                                        aSide2FirstNode,
04729                                        aSide2SecondNode,
04730                                        aSide2ThirdNode,
04731                                        false,
04732                                        CreatePolygons,
04733                                        CreatePolyedrs) );
04734 
04735   storeResult(anEditor);
04736 
04737   myMesh->GetMeshDS()->Modified();
04738   myMesh->SetIsModified( true );
04739 
04740   return error;
04741 }
04742 
04743 
04744 //=======================================================================
04745 //function : SewSideElements
04746 //purpose  :
04747 //=======================================================================
04748 
04749 SMESH::SMESH_MeshEditor::Sew_Error
04750 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
04751                                     const SMESH::long_array& IDsOfSide2Elements,
04752                                     CORBA::Long NodeID1OfSide1ToMerge,
04753                                     CORBA::Long NodeID1OfSide2ToMerge,
04754                                     CORBA::Long NodeID2OfSide1ToMerge,
04755                                     CORBA::Long NodeID2OfSide2ToMerge)
04756 {
04757   initData();
04758 
04759   SMESHDS_Mesh* aMesh = GetMeshDS();
04760 
04761   const SMDS_MeshNode* aFirstNode1ToMerge  = aMesh->FindNode( NodeID1OfSide1ToMerge );
04762   const SMDS_MeshNode* aFirstNode2ToMerge  = aMesh->FindNode( NodeID1OfSide2ToMerge );
04763   const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
04764   const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
04765 
04766   if (!aFirstNode1ToMerge ||
04767       !aFirstNode2ToMerge )
04768     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
04769   if (!aSecondNode1ToMerge||
04770       !aSecondNode2ToMerge)
04771     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
04772 
04773   TIDSortedElemSet aSide1Elems, aSide2Elems;
04774   arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
04775   arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
04776 
04777   TPythonDump() << "error = " << this << ".SewSideElements( "
04778                 << IDsOfSide1Elements << ", "
04779                 << IDsOfSide2Elements << ", "
04780                 << NodeID1OfSide1ToMerge << ", "
04781                 << NodeID1OfSide2ToMerge << ", "
04782                 << NodeID2OfSide1ToMerge << ", "
04783                 << NodeID2OfSide2ToMerge << ")";
04784 
04785   ::SMESH_MeshEditor anEditor( myMesh );
04786   SMESH::SMESH_MeshEditor::Sew_Error error =
04787     convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
04788                                          aFirstNode1ToMerge,
04789                                          aFirstNode2ToMerge,
04790                                          aSecondNode1ToMerge,
04791                                          aSecondNode2ToMerge));
04792 
04793   storeResult(anEditor);
04794 
04795   myMesh->GetMeshDS()->Modified();
04796   myMesh->SetIsModified( true );
04797 
04798   return error;
04799 }
04800 
04801 //================================================================================
04808 //================================================================================
04809 
04810 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
04811                                                    const SMESH::long_array& newIDs)
04812 {
04813   initData();
04814 
04815   const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
04816   if(!elem) return false;
04817 
04818   int nbn = newIDs.length();
04819   int i=0;
04820   vector<const SMDS_MeshNode*> aNodes(nbn);
04821   int nbn1=-1;
04822   for(; i<nbn; i++) {
04823     const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(newIDs[i]);
04824     if(aNode) {
04825       nbn1++;
04826       aNodes[nbn1] = aNode;
04827     }
04828   }
04829   TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
04830                 << ide << ", " << newIDs << " )";
04831 
04832   MESSAGE("ChangeElementNodes");
04833   bool res = GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
04834 
04835   myMesh->GetMeshDS()->Modified();
04836   if ( res )
04837     myMesh->SetIsModified( true );
04838 
04839   return res;
04840 }
04841 
04842 //================================================================================
04847 //================================================================================
04848 
04849 void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& anEditor)
04850 {
04851   if ( myPreviewMode ) { // --- MeshPreviewStruct filling ---
04852 
04853     list<int> aNodesConnectivity;
04854     typedef map<int, int> TNodesMap;
04855     TNodesMap nodesMap;
04856 
04857     TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( anEditor.GetMesh() );
04858     SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType;
04859 
04860     SMESHDS_Mesh* aMeshDS = anEditor.GetMeshDS();
04861     int nbEdges = aMeshDS->NbEdges();
04862     int nbFaces = aMeshDS->NbFaces();
04863     int nbVolum = aMeshDS->NbVolumes();
04864     switch ( previewType ) {
04865     case SMDSAbs_Edge  : nbFaces = nbVolum = 0; break;
04866     case SMDSAbs_Face  : nbEdges = nbVolum = 0; break;
04867     case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
04868     default:;
04869     }
04870     myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
04871     myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
04872     int i = 0, j = 0;
04873     SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
04874 
04875     while ( itMeshElems->more() ) {
04876       const SMDS_MeshElement* aMeshElem = itMeshElems->next();
04877       if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
04878         continue;
04879 
04880       SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
04881       while ( itElemNodes->more() ) {
04882         const SMDS_MeshNode* aMeshNode =
04883           static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
04884         int aNodeID = aMeshNode->GetID();
04885         TNodesMap::iterator anIter = nodesMap.find(aNodeID);
04886         if ( anIter == nodesMap.end() ) {
04887           // filling the nodes coordinates
04888           myPreviewData->nodesXYZ[j].x = aMeshNode->X();
04889           myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
04890           myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
04891           anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
04892           j++;
04893         }
04894         aNodesConnectivity.push_back(anIter->second);
04895       }
04896 
04897       // filling the elements types
04898       SMDSAbs_ElementType aType;
04899       bool isPoly;
04900       /*if (aMeshElem->GetType() == SMDSAbs_Volume) {
04901         aType = SMDSAbs_Node;
04902         isPoly = false;
04903         }
04904         else*/ {
04905         aType = aMeshElem->GetType();
04906         isPoly = aMeshElem->IsPoly();
04907       }
04908 
04909       myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
04910       myPreviewData->elementTypes[i].isPoly = isPoly;
04911       myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
04912       i++;
04913 
04914     }
04915     myPreviewData->nodesXYZ.length( j );
04916 
04917     // filling the elements connectivities
04918     list<int>::iterator aConnIter = aNodesConnectivity.begin();
04919     myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
04920     for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
04921       myPreviewData->elementConnectivities[i] = *aConnIter;
04922 
04923     return;
04924   }
04925 
04926   {
04927     // append new nodes into myLastCreatedNodes
04928     const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedNodes();
04929     int j = myLastCreatedNodes->length();
04930     int newLen = j + aSeq.Length();
04931     myLastCreatedNodes->length( newLen );
04932     for(int i=0; j<newLen; i++,j++)
04933       myLastCreatedNodes[j] = aSeq.Value(i+1)->GetID();
04934   }
04935   {
04936     // append new elements into myLastCreatedElems
04937     const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedElems();
04938     int j = myLastCreatedElems->length();
04939     int newLen = j + aSeq.Length();
04940     myLastCreatedElems->length( newLen );
04941     for(int i=0; j<newLen; i++,j++)
04942       myLastCreatedElems[j] = aSeq.Value(i+1)->GetID();
04943   }
04944 }
04945 
04946 //================================================================================
04950 //================================================================================
04951 
04952 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
04953 {
04954   return myPreviewData._retn();
04955 }
04956 
04957 //================================================================================
04962 //================================================================================
04963 
04964 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
04965 {
04966   return myLastCreatedNodes._retn();
04967 }
04968 
04969 //================================================================================
04974 //================================================================================
04975 
04976 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
04977 {
04978   return myLastCreatedElems._retn();
04979 }
04980 
04981 //=======================================================================
04982 //function : ConvertToQuadratic
04983 //purpose  :
04984 //=======================================================================
04985 
04986 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
04987 {
04988   ::SMESH_MeshEditor anEditor( myMesh );
04989   anEditor.ConvertToQuadratic(theForce3d);
04990   TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
04991   myMesh->GetMeshDS()->Modified();
04992   myMesh->SetIsModified( true );
04993 }
04994 
04995 //=======================================================================
04996 //function : ConvertFromQuadratic
04997 //purpose  :
04998 //=======================================================================
04999 
05000 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
05001 {
05002   ::SMESH_MeshEditor anEditor( myMesh );
05003   CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
05004   TPythonDump() << this << ".ConvertFromQuadratic()";
05005   myMesh->GetMeshDS()->Modified();
05006   if ( isDone )
05007     myMesh->SetIsModified( true );
05008   return isDone;
05009 }
05010 //================================================================================
05014 //================================================================================
05015 
05016 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean            theForce3d,
05017                                                   SMESH::SMESH_IDSource_ptr theObject)
05018   throw (SALOME::SALOME_Exception)
05019 {
05020   Unexpect aCatch(SALOME_SalomeException);
05021   TPythonDump pyDump;
05022   TIDSortedElemSet elems;
05023   if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
05024   {
05025     if ( elems.empty() )
05026     {
05027       ConvertToQuadratic( theForce3d );
05028     }
05029     else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
05030     {
05031       THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
05032     }
05033     else
05034     {
05035       ::SMESH_MeshEditor anEditor( myMesh );
05036       anEditor.ConvertToQuadratic(theForce3d, elems);
05037     }
05038   }
05039   myMesh->GetMeshDS()->Modified();
05040   myMesh->SetIsModified( true );
05041 
05042   pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
05043 }
05044 
05045 //================================================================================
05049 //================================================================================
05050 
05051 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
05052   throw (SALOME::SALOME_Exception)
05053 {
05054   Unexpect aCatch(SALOME_SalomeException);
05055   TPythonDump pyDump;
05056   TIDSortedElemSet elems;
05057   if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
05058   {
05059     if ( elems.empty() )
05060     {
05061       ConvertFromQuadratic();
05062     }
05063     else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
05064     {
05065       THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
05066     }
05067     else
05068     {
05069       ::SMESH_MeshEditor anEditor( myMesh );
05070       anEditor.ConvertFromQuadratic(elems);
05071     }
05072   }
05073   myMesh->GetMeshDS()->Modified();
05074   myMesh->SetIsModified( true );
05075 
05076   pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
05077 }
05078 
05079 //=======================================================================
05080 //function : makeMesh
05081 //purpose  : create a named imported mesh
05082 //=======================================================================
05083 
05084 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
05085 {
05086   SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
05087   SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
05088   SALOMEDS::Study_var study = gen->GetCurrentStudy();
05089   SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
05090   gen->SetName( meshSO, theMeshName, "Mesh" );
05091   gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
05092 
05093   return mesh._retn();
05094 }
05095 
05096 //=======================================================================
05097 //function : DumpGroupsList
05098 //purpose  :
05099 //=======================================================================
05100 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump &               theDumpPython,
05101                                         const SMESH::ListOfGroups * theGroupList)
05102 {
05103   bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
05104   if(isDumpGroupList) {
05105     theDumpPython << theGroupList << " = ";
05106   }
05107 }
05108 
05109 //================================================================================
05115 //================================================================================
05116 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
05117 {
05118   SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
05119   set<string> groupNames;
05120 
05121   // Get existing group names
05122   for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
05123     SMESH::SMESH_GroupBase_var aGroup = groups[i];
05124     if (CORBA::is_nil(aGroup))
05125       continue;
05126 
05127     groupNames.insert(aGroup->GetName());
05128   }
05129 
05130   // Find new name
05131   string name = thePrefix;
05132   int index = 0;
05133 
05134   while (!groupNames.insert(name).second) {
05135     if (index == 0) {
05136       name += "_1";
05137     }
05138     else {
05139       TCollection_AsciiString nbStr(index+1);
05140       name.resize( name.rfind('_')+1 );
05141       name += nbStr.ToCString();
05142     }
05143     ++index;
05144   }
05145 
05146   return name;
05147 }
05148 
05149 //================================================================================
05159 //================================================================================
05160 
05161 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
05162                                                 const SMESH::long_array& theModifiedElems )
05163 {
05164   initData();
05165 
05166   ::SMESH_MeshEditor aMeshEditor( myMesh );
05167   list< int > aListOfNodes;
05168   int i, n;
05169   for ( i = 0, n = theNodes.length(); i < n; i++ )
05170     aListOfNodes.push_back( theNodes[ i ] );
05171 
05172   list< int > aListOfElems;
05173   for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
05174     aListOfElems.push_back( theModifiedElems[ i ] );
05175 
05176   bool aResult = aMeshEditor.DoubleNodes( aListOfNodes, aListOfElems );
05177 
05178   myMesh->GetMeshDS()->Modified();
05179   storeResult( aMeshEditor) ;
05180   if ( aResult )
05181     myMesh->SetIsModified( true );
05182 
05183   // Update Python script
05184   TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
05185 
05186   return aResult;
05187 }
05188 
05189 //================================================================================
05198 //================================================================================
05199 
05200 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long              theNodeId,
05201                                                const SMESH::long_array& theModifiedElems )
05202 {
05203   SMESH::long_array_var aNodes = new SMESH::long_array;
05204   aNodes->length( 1 );
05205   aNodes[ 0 ] = theNodeId;
05206 
05207   TPythonDump pyDump; // suppress dump by the next line
05208 
05209   CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
05210 
05211   pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
05212 
05213   return done;
05214 }
05215 
05216 //================================================================================
05225 //================================================================================
05226 
05227 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
05228                                                    SMESH::SMESH_GroupBase_ptr theModifiedElems )
05229 {
05230   if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
05231     return false;
05232 
05233   SMESH::long_array_var aNodes = theNodes->GetListOfID();
05234   SMESH::long_array_var aModifiedElems;
05235   if ( !CORBA::is_nil( theModifiedElems ) )
05236     aModifiedElems = theModifiedElems->GetListOfID();
05237   else
05238   {
05239     aModifiedElems = new SMESH::long_array;
05240     aModifiedElems->length( 0 );
05241   }
05242 
05243   TPythonDump pyDump; // suppress dump by the next line
05244 
05245   bool done = DoubleNodes( aNodes, aModifiedElems );
05246 
05247   pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
05248 
05249   return done;
05250 }
05251 
05260 SMESH::SMESH_Group_ptr
05261 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
05262                                         SMESH::SMESH_GroupBase_ptr theModifiedElems )
05263 {
05264   SMESH::SMESH_Group_var aNewGroup;
05265 
05266   if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
05267     return aNewGroup._retn();
05268 
05269   // Duplicate nodes
05270   SMESH::long_array_var aNodes = theNodes->GetListOfID();
05271   SMESH::long_array_var aModifiedElems;
05272   if ( !CORBA::is_nil( theModifiedElems ) )
05273     aModifiedElems = theModifiedElems->GetListOfID();
05274   else {
05275     aModifiedElems = new SMESH::long_array;
05276     aModifiedElems->length( 0 );
05277   }
05278 
05279   TPythonDump pyDump; // suppress dump by the next line
05280 
05281   bool aResult = DoubleNodes( aNodes, aModifiedElems );
05282   if ( aResult )
05283   {
05284     // Create group with newly created nodes
05285     SMESH::long_array_var anIds = GetLastCreatedNodes();
05286     if (anIds->length() > 0) {
05287       string anUnindexedName (theNodes->GetName());
05288       string aNewName = generateGroupName(anUnindexedName + "_double");
05289       aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
05290       aNewGroup->Add(anIds);
05291       pyDump << aNewGroup << " = ";
05292     }
05293   }
05294 
05295   pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
05296          << theModifiedElems << " )";
05297 
05298   return aNewGroup._retn();
05299 }
05300 
05301 //================================================================================
05310 //================================================================================
05311 
05312 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
05313                                                     const SMESH::ListOfGroups& theModifiedElems )
05314 {
05315   initData();
05316 
05317   ::SMESH_MeshEditor aMeshEditor( myMesh );
05318 
05319   std::list< int > aNodes;
05320   int i, n, j, m;
05321   for ( i = 0, n = theNodes.length(); i < n; i++ )
05322   {
05323     SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
05324     if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
05325     {
05326       SMESH::long_array_var aCurr = aGrp->GetListOfID();
05327       for ( j = 0, m = aCurr->length(); j < m; j++ )
05328         aNodes.push_back( aCurr[ j ] );
05329     }
05330   }
05331 
05332   std::list< int > anElems;
05333   for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
05334   {
05335     SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
05336     if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
05337     {
05338       SMESH::long_array_var aCurr = aGrp->GetListOfID();
05339       for ( j = 0, m = aCurr->length(); j < m; j++ )
05340         anElems.push_back( aCurr[ j ] );
05341     }
05342   }
05343 
05344   bool aResult = aMeshEditor.DoubleNodes( aNodes, anElems );
05345 
05346   storeResult( aMeshEditor) ;
05347 
05348   myMesh->GetMeshDS()->Modified();
05349   if ( aResult )
05350     myMesh->SetIsModified( true );
05351 
05352 
05353   TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
05354 
05355   return aResult;
05356 }
05357 
05358 //================================================================================
05367 //================================================================================
05368 
05369 SMESH::SMESH_Group_ptr
05370 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
05371                                          const SMESH::ListOfGroups& theModifiedElems )
05372 {
05373   SMESH::SMESH_Group_var aNewGroup;
05374 
05375   TPythonDump pyDump; // suppress dump by the next line
05376 
05377   bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
05378 
05379   if ( aResult )
05380   {
05381     // Create group with newly created nodes
05382     SMESH::long_array_var anIds = GetLastCreatedNodes();
05383     if (anIds->length() > 0) {
05384       string anUnindexedName (theNodes[0]->GetName());
05385       string aNewName = generateGroupName(anUnindexedName + "_double");
05386       aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
05387       aNewGroup->Add(anIds);
05388       pyDump << aNewGroup << " = ";
05389     }
05390   }
05391 
05392   pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
05393          << theModifiedElems << " )";
05394 
05395   return aNewGroup._retn();
05396 }
05397 
05398 
05399 //================================================================================
05410 //================================================================================
05411 
05412 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
05413                                                    const SMESH::long_array& theNodesNot,
05414                                                    const SMESH::long_array& theAffectedElems )
05415 
05416 {
05417   initData();
05418 
05419   ::SMESH_MeshEditor aMeshEditor( myMesh );
05420 
05421   SMESHDS_Mesh* aMeshDS = GetMeshDS();
05422   TIDSortedElemSet anElems, aNodes, anAffected;
05423   arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
05424   arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
05425   arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
05426 
05427   bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
05428 
05429   storeResult( aMeshEditor) ;
05430 
05431   myMesh->GetMeshDS()->Modified();
05432   if ( aResult )
05433     myMesh->SetIsModified( true );
05434 
05435   // Update Python script
05436   TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
05437                 << theNodesNot << ", " << theAffectedElems << " )";
05438   return aResult;
05439 }
05440 
05441 //================================================================================
05453 //================================================================================
05454 
05455 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
05456                                                             const SMESH::long_array& theNodesNot,
05457                                                             GEOM::GEOM_Object_ptr    theShape )
05458 
05459 {
05460   initData();
05461 
05462   ::SMESH_MeshEditor aMeshEditor( myMesh );
05463 
05464   SMESHDS_Mesh* aMeshDS = GetMeshDS();
05465   TIDSortedElemSet anElems, aNodes;
05466   arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
05467   arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
05468 
05469   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
05470   bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
05471 
05472   storeResult( aMeshEditor) ;
05473 
05474   myMesh->GetMeshDS()->Modified();
05475   if ( aResult )
05476     myMesh->SetIsModified( true );
05477 
05478   // Update Python script
05479   TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
05480                 << theNodesNot << ", " << theShape << " )";
05481   return aResult;
05482 }
05483 
05484 //================================================================================
05494 //================================================================================
05495 
05496 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
05497                                                        SMESH::SMESH_GroupBase_ptr theNodesNot,
05498                                                        SMESH::SMESH_GroupBase_ptr theAffectedElems)
05499 {
05500   if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
05501     return false;
05502 
05503   initData();
05504 
05505   ::SMESH_MeshEditor aMeshEditor( myMesh );
05506 
05507   SMESHDS_Mesh* aMeshDS = GetMeshDS();
05508   TIDSortedElemSet anElems, aNodes, anAffected;
05509   idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
05510   idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
05511   idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
05512 
05513   bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
05514 
05515   storeResult( aMeshEditor) ;
05516 
05517   myMesh->GetMeshDS()->Modified();
05518   if ( aResult )
05519     myMesh->SetIsModified( true );
05520 
05521   // Update Python script
05522   TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
05523                 << theNodesNot << ", " << theAffectedElems << " )";
05524   return aResult;
05525 }
05526 
05537 SMESH::SMESH_Group_ptr
05538 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
05539                                            SMESH::SMESH_GroupBase_ptr theNodesNot,
05540                                            SMESH::SMESH_GroupBase_ptr theAffectedElems)
05541 {
05542   TPythonDump pyDump;
05543   SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
05544                                                                theNodesNot,
05545                                                                theAffectedElems,
05546                                                                true, false );
05547   SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
05548   SMESH::SMESH_Group_var     elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
05549 
05550   pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
05551          << theElems         << ", "
05552          << theNodesNot      << ", "
05553          << theAffectedElems << " )";
05554 
05555   return elemGroup._retn();
05556 }
05557 
05558 SMESH::ListOfGroups*
05559 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
05560                                             SMESH::SMESH_GroupBase_ptr theNodesNot,
05561                                             SMESH::SMESH_GroupBase_ptr theAffectedElems,
05562                                             CORBA::Boolean             theElemGroupNeeded,
05563                                             CORBA::Boolean             theNodeGroupNeeded)
05564 {
05565   SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
05566   SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
05567   aTwoGroups->length( 2 );
05568 
05569   if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
05570     return aTwoGroups._retn();
05571 
05572   initData();
05573 
05574   ::SMESH_MeshEditor aMeshEditor( myMesh );
05575 
05576   SMESHDS_Mesh* aMeshDS = GetMeshDS();
05577   TIDSortedElemSet anElems, aNodes, anAffected;
05578   idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
05579   idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
05580   idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
05581 
05582 
05583   bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
05584 
05585   storeResult( aMeshEditor) ;
05586   myMesh->GetMeshDS()->Modified();
05587 
05588   TPythonDump pyDump;
05589 
05590   if ( aResult )
05591   {
05592     myMesh->SetIsModified( true );
05593 
05594     // Create group with newly created elements
05595     CORBA::String_var elemGroupName = theElems->GetName();
05596     string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
05597     if ( !aMeshEditor.GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
05598     {
05599       SMESH::long_array_var anIds = GetLastCreatedElems();
05600       SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
05601       aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
05602       aNewElemGroup->Add(anIds);
05603     }
05604     if ( !aMeshEditor.GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
05605     {
05606       SMESH::long_array_var anIds = GetLastCreatedNodes();
05607       aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
05608       aNewNodeGroup->Add(anIds);
05609     }
05610   }
05611 
05612   // Update Python script
05613 
05614   pyDump << "[ ";
05615   if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
05616   else                            pyDump << aNewElemGroup << ", ";
05617   if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
05618   else                            pyDump << aNewNodeGroup << " ] = ";
05619 
05620   pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
05621          << theNodesNot        << ", "
05622          << theAffectedElems   << ", "
05623          << theElemGroupNeeded << ", "
05624          << theNodeGroupNeeded <<" )";
05625 
05626   aTwoGroups[0] = aNewElemGroup._retn();
05627   aTwoGroups[1] = aNewNodeGroup._retn();
05628   return aTwoGroups._retn();
05629 }
05630 
05631 //================================================================================
05642 //================================================================================
05643 
05644 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
05645                                                                SMESH::SMESH_GroupBase_ptr theNodesNot,
05646                                                                GEOM::GEOM_Object_ptr      theShape )
05647 
05648 {
05649   if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
05650     return false;
05651 
05652   initData();
05653 
05654   ::SMESH_MeshEditor aMeshEditor( myMesh );
05655 
05656   SMESHDS_Mesh* aMeshDS = GetMeshDS();
05657   TIDSortedElemSet anElems, aNodes, anAffected;
05658   idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
05659   idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
05660 
05661   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
05662   bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
05663 
05664   storeResult( aMeshEditor) ;
05665 
05666   myMesh->GetMeshDS()->Modified();
05667   if ( aResult )
05668     myMesh->SetIsModified( true );
05669 
05670   // Update Python script
05671   TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
05672                 << theNodesNot << ", " << theShape << " )";
05673   return aResult;
05674 }
05675 
05676 //================================================================================
05687 //================================================================================
05688 
05689 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
05690                              SMESHDS_Mesh*              theMeshDS,
05691                              TIDSortedElemSet&          theElemSet,
05692                              const bool                 theIsNodeGrp)
05693 {
05694   for ( int i = 0, n = theGrpList.length(); i < n; i++ )
05695   {
05696     SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
05697     if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
05698                                     : aGrp->GetType() != SMESH::NODE ) )
05699     {
05700       SMESH::long_array_var anIDs = aGrp->GetIDs();
05701       arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
05702     }
05703   }
05704 }
05705 
05706 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
05707                                                         const SMESH::ListOfGroups& theNodesNot,
05708                                                         const SMESH::ListOfGroups& theAffectedElems)
05709 {
05710   initData();
05711 
05712   ::SMESH_MeshEditor aMeshEditor( myMesh );
05713 
05714   SMESHDS_Mesh* aMeshDS = GetMeshDS();
05715   TIDSortedElemSet anElems, aNodes, anAffected;
05716   listOfGroupToSet(theElems, aMeshDS, anElems, false );
05717   listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
05718   listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
05719 
05720   bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
05721 
05722   storeResult( aMeshEditor) ;
05723 
05724   myMesh->GetMeshDS()->Modified();
05725   if ( aResult )
05726     myMesh->SetIsModified( true );
05727 
05728   // Update Python script
05729   TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
05730                 << &theNodesNot << ", " << &theAffectedElems << " )";
05731   return aResult;
05732 }
05733 
05734 //================================================================================
05745 //================================================================================
05746 
05747 SMESH::SMESH_Group_ptr
05748 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
05749                                             const SMESH::ListOfGroups& theNodesNot,
05750                                             const SMESH::ListOfGroups& theAffectedElems)
05751 {
05752   TPythonDump pyDump;
05753   SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
05754                                                                 theNodesNot,
05755                                                                 theAffectedElems,
05756                                                                 true, false );
05757   SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
05758   SMESH::SMESH_Group_var     elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
05759 
05760   pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
05761          << theElems         << ", "
05762          << theNodesNot      << ", "
05763          << theAffectedElems << " )";
05764 
05765   return elemGroup._retn();
05766 }
05767 
05768 SMESH::ListOfGroups*
05769 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
05770                                              const SMESH::ListOfGroups& theNodesNot,
05771                                              const SMESH::ListOfGroups& theAffectedElems,
05772                                              CORBA::Boolean             theElemGroupNeeded,
05773                                              CORBA::Boolean             theNodeGroupNeeded)
05774 {
05775   SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
05776   SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
05777   aTwoGroups->length( 2 );
05778   
05779   initData();
05780 
05781   ::SMESH_MeshEditor aMeshEditor( myMesh );
05782 
05783   SMESHDS_Mesh* aMeshDS = GetMeshDS();
05784   TIDSortedElemSet anElems, aNodes, anAffected;
05785   listOfGroupToSet(theElems, aMeshDS, anElems, false );
05786   listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
05787   listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
05788 
05789   bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
05790 
05791   storeResult( aMeshEditor) ;
05792 
05793   myMesh->GetMeshDS()->Modified();
05794   TPythonDump pyDump;
05795   if ( aResult )
05796   {
05797     myMesh->SetIsModified( true );
05798 
05799     // Create group with newly created elements
05800     CORBA::String_var elemGroupName = theElems[0]->GetName();
05801     string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
05802     if ( !aMeshEditor.GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
05803     {
05804       SMESH::long_array_var anIds = GetLastCreatedElems();
05805       SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
05806       aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
05807       aNewElemGroup->Add(anIds);
05808     }
05809     if ( !aMeshEditor.GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
05810     {
05811       SMESH::long_array_var anIds = GetLastCreatedNodes();
05812       aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
05813       aNewNodeGroup->Add(anIds);
05814     }
05815   }
05816 
05817   // Update Python script
05818 
05819   pyDump << "[ ";
05820   if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
05821   else                            pyDump << aNewElemGroup << ", ";
05822   if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
05823   else                            pyDump << aNewNodeGroup << " ] = ";
05824 
05825   pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
05826          << &theNodesNot       << ", "
05827          << &theAffectedElems  << ", "
05828          << theElemGroupNeeded << ", "
05829          << theNodeGroupNeeded << " )";
05830 
05831   aTwoGroups[0] = aNewElemGroup._retn();
05832   aTwoGroups[1] = aNewNodeGroup._retn();
05833   return aTwoGroups._retn();
05834 }
05835 
05836 //================================================================================
05848 //================================================================================
05849 
05850 CORBA::Boolean
05851 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
05852                                                  const SMESH::ListOfGroups& theNodesNot,
05853                                                  GEOM::GEOM_Object_ptr      theShape )
05854 {
05855   initData();
05856 
05857   ::SMESH_MeshEditor aMeshEditor( myMesh );
05858 
05859   SMESHDS_Mesh* aMeshDS = GetMeshDS();
05860   TIDSortedElemSet anElems, aNodes;
05861   listOfGroupToSet(theElems, aMeshDS, anElems,false );
05862   listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
05863 
05864   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
05865   bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
05866 
05867   storeResult( aMeshEditor) ;
05868 
05869   myMesh->GetMeshDS()->Modified();
05870   if ( aResult )
05871     myMesh->SetIsModified( true );
05872 
05873   // Update Python script
05874   TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
05875                 << &theNodesNot << ", " << theShape << " )";
05876   return aResult;
05877 }
05878 
05879 //================================================================================
05885 //================================================================================
05886 
05887 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
05888 {
05889   initData();
05890 
05891   ::SMESH_MeshEditor aMeshEditor( myMesh );
05892   bool aResult = aMeshEditor.Make2DMeshFrom3D();
05893   storeResult( aMeshEditor) ;
05894   myMesh->GetMeshDS()->Modified();
05895   TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
05896   return aResult;
05897 }
05898 
05899 //================================================================================
05911 //================================================================================
05912 
05913 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
05914                                                                  CORBA::Boolean createJointElems )
05915   throw (SALOME::SALOME_Exception)
05916 {
05917   initData();
05918 
05919   ::SMESH_MeshEditor aMeshEditor( myMesh );
05920 
05921   SMESHDS_Mesh* aMeshDS = GetMeshDS();
05922 
05923   vector<TIDSortedElemSet> domains;
05924   domains.clear();
05925 
05926   for ( int i = 0, n = theDomains.length(); i < n; i++ )
05927   {
05928     SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
05929     if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
05930     {
05931 //      if ( aGrp->GetType() != SMESH::VOLUME )
05932 //        THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
05933       TIDSortedElemSet domain;
05934       domain.clear();
05935       domains.push_back(domain);
05936       SMESH::long_array_var anIDs = aGrp->GetIDs();
05937       arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
05938     }
05939   }
05940 
05941   bool aResult = aMeshEditor.DoubleNodesOnGroupBoundaries( domains, createJointElems );
05942   // TODO publish the groups of flat elements in study
05943 
05944   storeResult( aMeshEditor) ;
05945   myMesh->GetMeshDS()->Modified();
05946 
05947   // Update Python script
05948   TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
05949       << ", " << createJointElems << " )";
05950   return aResult;
05951 }
05952 
05953 //================================================================================
05963 //================================================================================
05964 
05965 CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
05966 {
05967   initData();
05968 
05969   ::SMESH_MeshEditor aMeshEditor( myMesh );
05970 
05971   SMESHDS_Mesh* aMeshDS = GetMeshDS();
05972 
05973   vector<TIDSortedElemSet> faceGroups;
05974   faceGroups.clear();
05975 
05976   for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
05977   {
05978     SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
05979     if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
05980     {
05981       TIDSortedElemSet faceGroup;
05982       faceGroup.clear();
05983       faceGroups.push_back(faceGroup);
05984       SMESH::long_array_var anIDs = aGrp->GetIDs();
05985       arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
05986     }
05987   }
05988 
05989   bool aResult = aMeshEditor.CreateFlatElementsOnFacesGroups( faceGroups );
05990   // TODO publish the groups of flat elements in study
05991 
05992   storeResult( aMeshEditor) ;
05993   myMesh->GetMeshDS()->Modified();
05994 
05995   // Update Python script
05996   TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
05997   return aResult;
05998 }
05999 
06000 // issue 20749 ===================================================================
06015 // ================================================================================
06016 
06017 SMESH::SMESH_Mesh_ptr
06018 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
06019                                      SMESH::Bnd_Dimension      dim,
06020                                      const char*               groupName,
06021                                      const char*               meshName,
06022                                      CORBA::Boolean            toCopyElements,
06023                                      CORBA::Boolean            toCopyExistingBondary,
06024                                      SMESH::SMESH_Group_out    group)
06025 {
06026   initData();
06027 
06028   if ( dim > SMESH::BND_1DFROM2D )
06029     THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
06030 
06031   SMESHDS_Mesh* aMeshDS = GetMeshDS();
06032 
06033   SMESH::SMESH_Mesh_var mesh_var;
06034   SMESH::SMESH_Group_var group_var;
06035 
06036   TPythonDump pyDump;
06037 
06038   TIDSortedElemSet elements;
06039   SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
06040   if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
06041   {
06042     // mesh to fill in
06043     mesh_var =
06044       strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
06045     SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
06046     // other mesh
06047     SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
06048 
06049     // group of new boundary elements
06050     SMESH_Group* smesh_group = 0;
06051     if ( strlen(groupName) )
06052     {
06053       group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
06054       if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
06055         smesh_group = group_i->GetSmeshGroup();
06056     }
06057 
06058     // do it
06059     ::SMESH_MeshEditor aMeshEditor( myMesh );
06060     aMeshEditor.MakeBoundaryMesh( elements,
06061                                   ::SMESH_MeshEditor::Bnd_Dimension(dim),
06062                                   smesh_group,
06063                                   smesh_mesh,
06064                                   toCopyElements,
06065                                   toCopyExistingBondary);
06066     storeResult( aMeshEditor );
06067 
06068     if ( smesh_mesh )
06069       smesh_mesh->GetMeshDS()->Modified();
06070   }
06071 
06072   const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
06073 
06074   // result of MakeBoundaryMesh() is a tuple (mesh, group)
06075   if ( mesh_var->_is_nil() )
06076     pyDump << myMesh_i->_this() << ", ";
06077   else
06078     pyDump << mesh_var << ", ";
06079   if ( group_var->_is_nil() )
06080     pyDump << "_NoneGroup = "; // assignment to None is forbiden
06081   else
06082     pyDump << group_var << " = ";
06083   pyDump << this << ".MakeBoundaryMesh( "
06084          << idSource << ", "
06085          << "SMESH." << dimName[int(dim)] << ", "
06086          << "'" << groupName << "', "
06087          << "'" << meshName<< "', "
06088          << toCopyElements << ", "
06089          << toCopyExistingBondary << ")";
06090 
06091   group = group_var._retn();
06092   return mesh_var._retn();
06093 }
06094 
06095 //================================================================================
06110 //================================================================================
06111 
06112 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
06113                                                      const char* groupName,
06114                                                      const char* meshName,
06115                                                      CORBA::Boolean toCopyAll,
06116                                                      const SMESH::ListOfIDSources& groups,
06117                                                      SMESH::SMESH_Mesh_out mesh,
06118                                                      SMESH::SMESH_Group_out group)
06119   throw (SALOME::SALOME_Exception)
06120 {
06121   Unexpect aCatch(SALOME_SalomeException);
06122 
06123   initData();
06124 
06125   if ( dim > SMESH::BND_1DFROM2D )
06126     THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
06127 
06128   // separate groups belonging to this and other mesh
06129   SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
06130   SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
06131   groupsOfThisMesh->length( groups.length() );
06132   groupsOfOtherMesh->length( groups.length() );
06133   int nbGroups = 0, nbGroupsOfOtherMesh = 0;
06134   for ( int i = 0; i < groups.length(); ++i )
06135   {
06136     SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
06137     if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
06138       groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
06139     else
06140       groupsOfThisMesh[ nbGroups++ ] = groups[i];
06141     if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
06142       THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
06143   }
06144   groupsOfThisMesh->length( nbGroups );
06145   groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
06146 
06147   int nbAdded = 0;
06148   TPythonDump pyDump;
06149 
06150   if ( nbGroupsOfOtherMesh > 0 )
06151   {
06152     // process groups belonging to another mesh
06153     SMESH::SMESH_Mesh_var    otherMesh = groupsOfOtherMesh[0]->GetMesh();
06154     SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
06155     nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
06156                                              groupsOfOtherMesh, mesh, group );
06157   }
06158 
06159   SMESH::SMESH_Mesh_var mesh_var;
06160   SMESH::SMESH_Group_var group_var;
06161 
06162   // get mesh to fill
06163   mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
06164   const bool toCopyMesh = ( strlen( meshName ) > 0 );
06165   if ( toCopyMesh )
06166   {
06167     if ( toCopyAll )
06168       mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
06169                                                       meshName,
06170                                                       /*toCopyGroups=*/false,
06171                                                       /*toKeepIDs=*/true);
06172     else
06173       mesh_var = makeMesh(meshName);
06174   }
06175   SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
06176   SMESH_Mesh*  tgtMesh = &mesh_i->GetImpl();
06177 
06178   // source mesh
06179   SMESH_Mesh*     srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
06180   SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
06181 
06182   // group of boundary elements
06183   SMESH_Group* smesh_group = 0;
06184   SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
06185   if ( strlen(groupName) )
06186   {
06187     SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
06188     group_var = mesh_i->CreateGroup( groupType, groupName );
06189     if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
06190       smesh_group = group_i->GetSmeshGroup();
06191   }
06192 
06193   TIDSortedElemSet elements;
06194 
06195   if ( groups.length() > 0 )
06196   {
06197     for ( int i = 0; i < nbGroups; ++i )
06198     {
06199       elements.clear();
06200       if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
06201       {
06202         SMESH::Bnd_Dimension bdim = 
06203           ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
06204         ::SMESH_MeshEditor aMeshEditor( srcMesh );
06205         nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
06206                                                  ::SMESH_MeshEditor::Bnd_Dimension(bdim),
06207                                                  smesh_group,
06208                                                  tgtMesh,
06209                                                  /*toCopyElements=*/false,
06210                                                  /*toCopyExistingBondary=*/srcMesh != tgtMesh,
06211                                                  /*toAddExistingBondary=*/true,
06212                                                  /*aroundElements=*/true);
06213         storeResult( aMeshEditor );
06214       }
06215     }
06216   }
06217   else
06218   {
06219     ::SMESH_MeshEditor aMeshEditor( srcMesh );
06220     nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
06221                                              ::SMESH_MeshEditor::Bnd_Dimension(dim),
06222                                              smesh_group,
06223                                              tgtMesh,
06224                                              /*toCopyElements=*/false,
06225                                              /*toCopyExistingBondary=*/srcMesh != tgtMesh,
06226                                              /*toAddExistingBondary=*/true);
06227     storeResult( aMeshEditor );
06228   }
06229   tgtMesh->GetMeshDS()->Modified();
06230 
06231   const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
06232 
06233   // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
06234   pyDump << "nbAdded, ";
06235   if ( mesh_var->_is_nil() )
06236     pyDump << myMesh_i->_this() << ", ";
06237   else
06238     pyDump << mesh_var << ", ";
06239   if ( group_var->_is_nil() )
06240     pyDump << "_NoneGroup = "; // assignment to None is forbiden
06241   else
06242     pyDump << group_var << " = ";
06243   pyDump << this << ".MakeBoundaryElements( "
06244          << "SMESH." << dimName[int(dim)] << ", "
06245          << "'" << groupName << "', "
06246          << "'" << meshName<< "', "
06247          << toCopyAll << ", "
06248          << groups << ")";
06249 
06250   mesh  = mesh_var._retn();
06251   group = group_var._retn();
06252   return nbAdded;
06253 }