Version: 6.3.1

src/SMESH_I/SMESH_MeshEditor_i.cxx

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