X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH_I%2FSMESH_MeshEditor_i.cxx;h=e469b70393137718ceb3c7f453aa631e2ceb7b2b;hp=7392590f42c87eb52de32c43e4c612110e7bc619;hb=a11ec0f515b86d30e1617e522a2294d3320cb3c7;hpb=f3ae24b365cd2e7cee7951d7c144d8d336b57be1 diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index 7392590f4..d96c5c99e 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -6,7 +6,7 @@ // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,7 +23,7 @@ // Author : Nicolas REJNERI // Module : SMESH -#ifdef WNT +#ifdef WIN32 #define NOMINMAX #endif @@ -42,7 +42,6 @@ #include "SMDS_Mesh0DElement.hxx" #include "SMDS_MeshFace.hxx" #include "SMDS_MeshVolume.hxx" -#include "SMDS_PolyhedralVolumeOfNodes.hxx" #include "SMDS_SetIterator.hxx" #include "SMDS_VolumeTool.hxx" #include "SMESHDS_Group.hxx" @@ -75,15 +74,8 @@ #include #include -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 -#define NO_CAS_CATCH -#endif - #include - -#ifdef NO_CAS_CATCH #include -#endif #include #include @@ -109,12 +101,10 @@ namespace MeshEditor_I { SMDSAbs_ElementType myPreviewType; // type to show //!< Constructor TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) { - _isShapeToMesh = (_id =_studyId = 0); + _isShapeToMesh = (_id = 0); _myMeshDS = new SMESHDS_Mesh( _id, true ); myPreviewType = previewElements; } - //!< Destructor - virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; } //!< Copy a set of elements void Copy(const TIDSortedElemSet & theElements, TIDSortedElemSet& theCopyElements, @@ -145,9 +135,9 @@ namespace MeshEditor_I { { // copy element nodes int anElemNbNodes = anElem->NbNodes(); - vector< int > anElemNodesID( anElemNbNodes ) ; + vector< smIdType > anElemNodesID( anElemNbNodes ) ; SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator(); - for ( int i = 0; itElemNodes->more(); i++) + for ( smIdType i = 0; itElemNodes->more(); i++) { const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() ); Copy( anElemNode ); @@ -155,20 +145,11 @@ namespace MeshEditor_I { } // creates a corresponding element on copied nodes - SMDS_MeshElement* anElemCopy = 0; - if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume ) - { - const SMDS_VtkVolume* ph = - dynamic_cast (anElem); - if ( ph ) - anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID - (anElemNodesID, ph->GetQuantities(),anElem->GetID()); - } - else { - anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID, - anElem->GetType(), - anElem->IsPoly() ); - } + ::SMESH_MeshEditor::ElemFeatures elemType; + elemType.Init( anElem, /*basicOnly=*/false ); + elemType.SetID( anElem->GetID() ); + SMDS_MeshElement* anElemCopy = + ::SMESH_MeshEditor(this).AddElement( anElemNodesID, elemType ); return anElemCopy; } //!< Copy a node @@ -177,6 +158,19 @@ namespace MeshEditor_I { return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(), anElemNode->GetID()); } + void RemoveAll() + { + GetMeshDS()->ClearMesh(); + } + void Remove( SMDSAbs_ElementType type ) + { + Remove( GetMeshDS()->elementsIterator( type )); + } + void Remove( SMDS_ElemIteratorPtr eIt ) + { + while ( eIt->more() ) + GetMeshDS()->RemoveFreeElement( eIt->next(), /*sm=*/0, /*fromGroups=*/false ); + } };// struct TPreviewMesh static SMESH_NodeSearcher * theNodeSearcher = 0; @@ -184,7 +178,7 @@ namespace MeshEditor_I { //============================================================================= /*! - * \brief Deleter of theNodeSearcher at any compute event occured + * \brief Deleter of theNodeSearcher and theElementSearcher at any compute event occurred */ //============================================================================= @@ -199,8 +193,8 @@ namespace MeshEditor_I { //!< Delete theNodeSearcher static void Delete() { - if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0; - if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0; + if ( theNodeSearcher ) { delete theNodeSearcher; } theNodeSearcher = 0; + if ( theElementSearcher ) { delete theElementSearcher; } theElementSearcher = 0; } typedef map < int, SMESH_subMesh * > TDependsOnMap; //!< The meshod called by submesh: do my main job @@ -223,22 +217,22 @@ namespace MeshEditor_I { } myMesh = mesh; myMeshPartIOR = meshPartIOR; - if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) { - const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn(); - TDependsOnMap::const_iterator sm; - for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++) - sm->second->SetEventListener( this, 0, sm->second ); + SMESH_subMesh* sm = mesh->GetSubMesh( mesh->GetShapeToMesh() ); + SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true ); + while ( smIt->more() ) + { + sm = smIt->next(); + sm->SetEventListener( this, 0, sm ); } } } //!< delete self from all submeshes void Unset(SMESH_Mesh* mesh) { - if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) { - const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn(); - TDependsOnMap::const_iterator sm; - for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++) - sm->second->DeleteEventListener( this ); + if ( SMESH_subMesh* sm = mesh->GetSubMeshContaining(1) ) { + SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true ); + while ( smIt->more() ) + smIt->next()->DeleteEventListener( this ); } myMesh = 0; } @@ -270,98 +264,69 @@ namespace MeshEditor_I { */ //================================================================================ - void arrayToSet(const SMESH::long_array & IDs, - const SMESHDS_Mesh* aMesh, - TIDSortedElemSet& aMap, - const SMDSAbs_ElementType aType = SMDSAbs_All ) + void arrayToSet(const SMESH::smIdType_array & IDs, + const SMESHDS_Mesh* aMesh, + TIDSortedElemSet& aMap, + const SMDSAbs_ElementType aType = SMDSAbs_All, + SMDS_MeshElement::Filter* aFilter = NULL) { SMDS_MeshElement::NonNullFilter filter1; SMDS_MeshElement::TypeFilter filter2( aType ); - SMDS_MeshElement::Filter & filter = - ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter&) filter1 : filter2; + + if ( aFilter == NULL ) + aFilter = ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter*) &filter1 : (SMDS_MeshElement::Filter*) &filter2; + + SMDS_MeshElement::Filter & filter = *aFilter; if ( aType == SMDSAbs_Node ) - for (int i=0; iFindNode( IDs[i] ); if ( filter( elem )) aMap.insert( aMap.end(), elem ); } else - for (int i=0; iFindElement( IDs[i] ); if ( filter( elem )) aMap.insert( aMap.end(), elem ); } } - //================================================================================ - /*! - * \brief Retrieve elements of given type from SMESH_IDSource - */ - //================================================================================ - - bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource, - const SMESHDS_Mesh* theMeshDS, - TIDSortedElemSet& theElemSet, - const SMDSAbs_ElementType theType, - const bool emptyIfIsMesh=false) - - { - if ( CORBA::is_nil( theIDSource ) ) - return false; - if ( emptyIfIsMesh && SMESH::DownCast( theIDSource )) - return true; - SMESH::long_array_var anIDs = theIDSource->GetIDs(); - if ( anIDs->length() == 0 ) - return false; - SMESH::array_of_ElementType_var types = theIDSource->GetTypes(); - if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes - { - if ( theType == SMDSAbs_All || theType == SMDSAbs_Node ) - arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node ); - else - return false; - } - else - { - arrayToSet( anIDs, theMeshDS, theElemSet, theType); - return bool(anIDs->length()) == bool(theElemSet.size()); - } - return true; - } //================================================================================ /*! * \brief Retrieve nodes from SMESH_IDSource */ //================================================================================ - void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject, - const SMESHDS_Mesh* theMeshDS, - TIDSortedNodeSet& theNodeSet) + void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject, + const SMESHDS_Mesh* theMeshDS, + TIDSortedNodeSet& theNodeSet) { if ( CORBA::is_nil( theObject ) ) return; - SMESH::array_of_ElementType_var types = theObject->GetTypes(); - SMESH::long_array_var aElementsId = theObject->GetIDs(); - if ( types->length() == 1 && types[0] == SMESH::NODE) - { - for(int i = 0; i < aElementsId->length(); i++) - if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] )) - theNodeSet.insert( theNodeSet.end(), n); - } - else if ( SMESH::DownCast( theObject )) + if ( SMESH::DownCast( theObject )) { - SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator(); - while ( nIt->more( )) - if( const SMDS_MeshElement * elem = nIt->next() ) + for ( SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator(); nIt->more(); ) + if ( const SMDS_MeshElement * elem = nIt->next() ) theNodeSet.insert( elem->begin_nodes(), elem->end_nodes()); } else { - for(int i = 0; i < aElementsId->length(); i++) - if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] )) - theNodeSet.insert( elem->begin_nodes(), elem->end_nodes()); + SMESH::array_of_ElementType_var types = theObject->GetTypes(); + SMESH::smIdType_array_var aElementsId = theObject->GetIDs(); + if ( types->length() == 1 && types[0] == SMESH::NODE) + { + for ( CORBA::ULong i = 0; i < aElementsId->length(); i++ ) + if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] )) + theNodeSet.insert( theNodeSet.end(), n); + } + else + { + for ( CORBA::ULong i = 0; i < aElementsId->length(); i++ ) + if ( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] )) + theNodeSet.insert( elem->begin_nodes(), elem->end_nodes()); + } } } @@ -380,13 +345,14 @@ namespace MeshEditor_I { SMDSAbs_ElementType elemType = (*theElements.begin())->GetType(); bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() ); if ( sameElemType && - theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() ) + theMeshDS->GetMeshInfo().NbElements( elemType ) == (int) theElements.size() ) return; // all the elements are in theElements if ( !sameElemType ) elemType = SMDSAbs_All; - TIDSortedElemSet visitedNodes; + vector isNodeChecked( theMeshDS->NbNodes(), false ); + TIDSortedElemSet::const_iterator elemIt = theElements.begin(); for ( ; elemIt != theElements.end(); ++elemIt ) { @@ -395,8 +361,9 @@ namespace MeshEditor_I { while ( --i != -1 ) { const SMDS_MeshNode* n = e->GetNode( i ); - if ( visitedNodes.insert( n ).second ) + if ( !isNodeChecked[ n->GetID() ]) { + isNodeChecked[ n->GetID() ] = true; SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType); while ( invIt->more() ) { @@ -416,8 +383,10 @@ namespace MeshEditor_I { */ //================================================================================ - string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type) + string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type = SMESH::ALL ) { + if ( SMESH::DownCast( theMeshPart )) + return ""; string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart ); if ( SMESH_Group_i* group_i = SMESH::DownCast( theMeshPart )) // take into account passible group modification @@ -454,11 +423,26 @@ SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview): SMESH_MeshEditor_i::~SMESH_MeshEditor_i() { + PortableServer::POA_var poa = SMESH_Gen_i::GetPOA(); + PortableServer::ObjectId_var anObjectId = poa->servant_to_id(this); + poa->deactivate_object(anObjectId.in()); + //deleteAuxIDSources(); delete myPreviewMesh; myPreviewMesh = 0; delete myPreviewEditor; myPreviewEditor = 0; } +//================================================================================ +/*! + * \brief Returns the mesh + */ +//================================================================================ + +SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::GetMesh() +{ + return myMesh_i->_this(); +} + //================================================================================ /*! * \brief Clear members @@ -468,22 +452,22 @@ SMESH_MeshEditor_i::~SMESH_MeshEditor_i() void SMESH_MeshEditor_i::initData(bool deleteSearchers) { if ( myIsPreviewMode ) { - if ( myPreviewMesh ) myPreviewMesh->Clear(); + if ( myPreviewMesh ) myPreviewMesh->RemoveAll(); } else { if ( deleteSearchers ) TSearchersDeleter::Delete(); } getEditor().GetError().reset(); - getEditor().CrearLastCreated(); + getEditor().ClearLastCreated(); } //================================================================================ /*! * \brief Increment mesh modif time and optionally record that the performed - * modification may influence futher mesh re-compute. - * \param [in] isReComputeSafe - true if the modification does not infulence - * futher mesh re-compute + * modification may influence further mesh re-compute. + * \param [in] isReComputeSafe - true if the modification does not influence + * further mesh re-compute */ //================================================================================ @@ -515,7 +499,7 @@ void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe ) * \brief Initialize and return myPreviewMesh * \param previewElements - type of elements to show in preview * - * WARNING: call it once par a method! + * WARNING: call it once per method! */ //================================================================================ @@ -539,21 +523,22 @@ TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewEle //================================================================================ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData() - throw (SALOME::SALOME_Exception) -{ +{ SMESH_TRY; const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() ); - if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling --- - + if ( myIsPreviewMode || hasBadElems ) + { list aNodesConnectivity; typedef map TNodesMap; TNodesMap nodesMap; SMESHDS_Mesh* aMeshDS; - std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS; + std::unique_ptr< SMESH_MeshPartDS > aMeshPartDS; if ( hasBadElems ) { - aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements )); + const list& badElems = + static_cast( getEditor().GetError().get() )->myBadElements; + aMeshPartDS.reset( new SMESH_MeshPartDS( badElems )); aMeshDS = aMeshPartDS.get(); } else { @@ -562,7 +547,7 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData() myPreviewData = new SMESH::MeshPreviewStruct(); myPreviewData->nodesXYZ.length(aMeshDS->NbNodes()); - + SMDSAbs_ElementType previewType = SMDSAbs_All; if ( !hasBadElems ) if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) { @@ -582,10 +567,13 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData() while ( itMeshElems->more() ) { const SMDS_MeshElement* aMeshElem = itMeshElems->next(); - SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator(); + SMDS_NodeIteratorPtr itElemNodes = + (( aMeshElem->GetEntityType() == SMDSEntity_Quad_Polygon ) ? + aMeshElem->interlacedNodesIterator() : + aMeshElem->nodeIterator() ); while ( itElemNodes->more() ) { const SMDS_MeshNode* aMeshNode = itElemNodes->next(); - int aNodeID = aMeshNode->GetID(); + smIdType aNodeID = aMeshNode->GetID(); TNodesMap::iterator anIter = nodesMap.find(aNodeID); if ( anIter == nodesMap.end() ) { // filling the nodes coordinates @@ -627,16 +615,15 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData() */ //================================================================================ -SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes() - throw (SALOME::SALOME_Exception) +SMESH::smIdType_array* SMESH_MeshEditor_i::GetLastCreatedNodes() { SMESH_TRY; - SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array(); + SMESH::smIdType_array_var myLastCreatedNodes = new SMESH::smIdType_array(); const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes(); - myLastCreatedNodes->length( aSeq.Length() ); - for (int i = 1; i <= aSeq.Length(); i++) - myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID(); + myLastCreatedNodes->length( aSeq.size() ); + for ( size_t i = 0; i < aSeq.size(); i++) + myLastCreatedNodes[i] = aSeq[i]->GetID(); return myLastCreatedNodes._retn(); SMESH_CATCH( SMESH::throwCorbaException ); @@ -650,16 +637,15 @@ SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes() */ //================================================================================ -SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems() - throw (SALOME::SALOME_Exception) +SMESH::smIdType_array* SMESH_MeshEditor_i::GetLastCreatedElems() { SMESH_TRY; - SMESH::long_array_var myLastCreatedElems = new SMESH::long_array(); + SMESH::smIdType_array_var myLastCreatedElems = new SMESH::smIdType_array(); const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems(); - myLastCreatedElems->length( aSeq.Length() ); - for ( int i = 1; i <= aSeq.Length(); i++ ) - myLastCreatedElems[i-1] = aSeq.Value(i)->GetID(); + myLastCreatedElems->length( aSeq.size() ); + for ( size_t i = 0; i < aSeq.size(); i++ ) + myLastCreatedElems[i] = aSeq[i]->GetID(); return myLastCreatedElems._retn(); SMESH_CATCH( SMESH::throwCorbaException ); @@ -671,22 +657,21 @@ SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems() //purpose : Clears sequences of last created elements and nodes //======================================================================= -void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception) +void SMESH_MeshEditor_i::ClearLastCreated() { SMESH_TRY; - getEditor().CrearLastCreated(); + getEditor().ClearLastCreated(); SMESH_CATCH( SMESH::throwCorbaException ); } //======================================================================= /* - * Returns description of an error/warning occured during the last operation + * Returns description of an error/warning occurred during the last operation * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API */ //======================================================================= SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError() - throw (SALOME::SALOME_Exception) { SMESH_TRY; SMESH::ComputeError_var errOut = new SMESH::ComputeError; @@ -696,7 +681,7 @@ SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError() errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0 errOut->comment = errIn->myComment.c_str(); errOut->subShapeID = -1; - errOut->hasBadMesh = !errIn->myBadElements.empty(); + errOut->hasBadMesh = errIn->HasBadElems(); } else { @@ -719,16 +704,16 @@ SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError() struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource, public virtual SALOME::GenericObj_i { - SMESH::long_array _ids; - SMESH::ElementType _type; - SMESH::SMESH_Mesh_ptr _mesh; - SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); } - SMESH::long_array* GetMeshInfo() { return 0; } - SMESH::long_array* GetNbElementsByType() + SMESH::smIdType_array _ids; + SMESH::ElementType _type; + SMESH::SMESH_Mesh_ptr _mesh; + SMESH::smIdType_array* GetIDs() { return new SMESH::smIdType_array( _ids ); } + SMESH::smIdType_array* GetMeshInfo() { return 0; } + SMESH::smIdType_array* GetNbElementsByType() { - SMESH::long_array_var aRes = new SMESH::long_array(); + SMESH::smIdType_array_var aRes = new SMESH::smIdType_array(); aRes->length(SMESH::NB_ELEMENT_TYPES); - for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++) + for (smIdType i = 0; i < SMESH::NB_ELEMENT_TYPES; i++) aRes[ i ] = ( i == _type ) ? _ids.length() : 0; return aRes._retn(); } @@ -743,21 +728,22 @@ struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource, } return types._retn(); } + SALOMEDS::TMPFile* GetVtkUgStream() + { + SALOMEDS::TMPFile_var SeqFile; + return SeqFile._retn(); + } }; -SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids, - SMESH::ElementType type) +SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::smIdType_array& ids, + SMESH::ElementType type) { - // if ( myAuxIDSources.size() > 10 ) { - // delete myAuxIDSources.front(); - // myAuxIDSources.pop_front(); - // } - _IDSource* idSrc = new _IDSource; idSrc->_mesh = myMesh_i->_this(); idSrc->_ids = ids; idSrc->_type = type; - //myAuxIDSources.push_back( idSrc ); + if ( type == SMESH::ALL && ids.length() > 0 ) + idSrc->_type = myMesh_i->GetElementType( ids[0], true ); SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this(); @@ -769,12 +755,12 @@ bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSourc return SMESH::DownCast( idSource ); } -CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource, - int& nbIds) +SMESH::smIdType* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource, + SMESH::smIdType& nbIds) { if ( _IDSource* tmpIdSource = SMESH::DownCast( idSource )) { - nbIds = (int) tmpIdSource->_ids.length(); + nbIds = (SMESH::smIdType) tmpIdSource->_ids.length(); return & tmpIdSource->_ids[0]; } nbIds = 0; @@ -796,15 +782,14 @@ CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idS //============================================================================= CORBA::Boolean -SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements) - throw (SALOME::SALOME_Exception) +SMESH_MeshEditor_i::RemoveElements(const SMESH::smIdType_array & IDsOfElements) { SMESH_TRY; initData(); - list< int > IdList; + list< smIdType > IdList; - for (int i = 0; i < IDsOfElements.length(); i++) + for ( SMESH::smIdType i = 0; i < IDsOfElements.length(); i++ ) IdList.push_back( IDsOfElements[i] ); // Update Python script @@ -826,14 +811,13 @@ SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements) */ //============================================================================= -CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes) - throw (SALOME::SALOME_Exception) +CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::smIdType_array & IDsOfNodes) { SMESH_TRY; initData(); - list< int > IdList; - for (int i = 0; i < IDsOfNodes.length(); i++) + list< smIdType > IdList; + for ( SMESH::smIdType i = 0; i < IDsOfNodes.length(); i++) IdList.push_back( IDsOfNodes[i] ); // Update Python script @@ -854,8 +838,7 @@ CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNo */ //============================================================================= -CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes() - throw (SALOME::SALOME_Exception) +SMESH::smIdType SMESH_MeshEditor_i::RemoveOrphanNodes() { SMESH_TRY; initData(); @@ -869,13 +852,11 @@ CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes() SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq ); // remove orphan nodes (if there are any) - list< int > IdList; - for ( int i = 0; i < seq.size(); i++ ) - IdList.push_back( seq[i] ); + list< smIdType > IdList( seq.begin(), seq.end() ); - int nbNodesBefore = myMesh->NbNodes(); + SMESH::smIdType nbNodesBefore = myMesh->NbNodes(); getEditor().Remove( IdList, true ); - int nbNodesAfter = myMesh->NbNodes(); + SMESH::smIdType nbNodesAfter = myMesh->NbNodes(); declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693 return nbNodesBefore - nbNodesAfter; @@ -890,8 +871,7 @@ CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes() */ //============================================================================= -CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z) - throw (SALOME::SALOME_Exception) +SMESH::smIdType SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z) { SMESH_TRY; initData(); @@ -915,14 +895,18 @@ CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA:: */ //============================================================================= -CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode) - throw (SALOME::SALOME_Exception) +SMESH::smIdType SMESH_MeshEditor_i::Add0DElement(SMESH::smIdType IDOfNode, + CORBA::Boolean DuplicateElements) { SMESH_TRY; initData(); const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode); - SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode); + SMDS_ElemIteratorPtr it0D = aNode->GetInverseElementIterator( SMDSAbs_0DElement ); + + SMDS_MeshElement* elem = 0; + if ( DuplicateElements || !it0D->more() ) + elem = getMeshDS()->Add0DElement(aNode); // Update Python script TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )"; @@ -941,8 +925,7 @@ CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode) */ //============================================================================= -CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter) - throw (SALOME::SALOME_Exception) +SMESH::smIdType SMESH_MeshEditor_i::AddBall(SMESH::smIdType IDOfNode, CORBA::Double diameter) { SMESH_TRY; initData(); @@ -971,18 +954,17 @@ CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diam */ //============================================================================= -CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes) - throw (SALOME::SALOME_Exception) +SMESH::smIdType SMESH_MeshEditor_i::AddEdge(const SMESH::smIdType_array & IDsOfNodes) { SMESH_TRY; initData(); - int NbNodes = IDsOfNodes.length(); + SMESH::smIdType NbNodes = IDsOfNodes.length(); SMDS_MeshElement* elem = 0; if (NbNodes == 2) { - CORBA::Long index1 = IDsOfNodes[0]; - CORBA::Long index2 = IDsOfNodes[1]; + SMESH::smIdType index1 = IDsOfNodes[0]; + SMESH::smIdType index2 = IDsOfNodes[1]; elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1), getMeshDS()->FindNode(index2)); @@ -991,9 +973,9 @@ CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes) << index1 << ", " << index2 <<" ])"; } if (NbNodes == 3) { - CORBA::Long n1 = IDsOfNodes[0]; - CORBA::Long n2 = IDsOfNodes[1]; - CORBA::Long n12 = IDsOfNodes[2]; + SMESH::smIdType n1 = IDsOfNodes[0]; + SMESH::smIdType n2 = IDsOfNodes[1]; + SMESH::smIdType n12 = IDsOfNodes[2]; elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1), getMeshDS()->FindNode(n2), getMeshDS()->FindNode(n12)); @@ -1015,8 +997,7 @@ CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes) */ //============================================================================= -CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes) - throw (SALOME::SALOME_Exception) +SMESH::smIdType SMESH_MeshEditor_i::AddFace(const SMESH::smIdType_array & IDsOfNodes) { SMESH_TRY; initData(); @@ -1063,8 +1044,43 @@ CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes) * AddPolygonalFace */ //============================================================================= -CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes) - throw (SALOME::SALOME_Exception) + +SMESH::smIdType SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::smIdType_array & IDsOfNodes) +{ + SMESH_TRY; + initData(); + + int NbNodes = IDsOfNodes.length(); + std::vector nodes (NbNodes); + for (int i = 0; i < NbNodes; i++) + if ( ! ( nodes[i] = getMeshDS()->FindNode( IDsOfNodes[i] ))) + return 0; + + if ( NbNodes == 0 ) + { + INFOS("Polygon without nodes is forbidden"); + return 0; + } + + const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes); + + // Update Python script + TPythonDump() <<"faceID = "<GetID() : 0; + + SMESH_CATCH( SMESH::throwCorbaException ); + return 0; +} + +//============================================================================= +/*! + * AddQuadPolygonalFace + */ +//============================================================================= + +SMESH::smIdType SMESH_MeshEditor_i::AddQuadPolygonalFace (const SMESH::smIdType_array & IDsOfNodes) { SMESH_TRY; initData(); @@ -1074,7 +1090,13 @@ CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsO for (int i = 0; i < NbNodes; i++) nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]); - const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes); + if ( NbNodes == 0 ) + { + INFOS("Polygon without nodes is forbidden"); + return 0; + } + + const SMDS_MeshElement* elem = getMeshDS()->AddQuadPolygonalFace(nodes); // Update Python script TPythonDump() <<"faceID = "<AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7], + n[8],n[9],n[10],n[11],n[12],n[13],n[14], + n[15],n[16],n[17]); + break; case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7], n[8],n[9],n[10],n[11],n[12],n[13],n[14], n[15],n[16],n[17],n[18],n[19], @@ -1149,9 +1174,8 @@ CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes) * AddPolyhedralVolume */ //============================================================================= -CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes, +SMESH::smIdType SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::smIdType_array & IDsOfNodes, const SMESH::long_array & Quantities) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -1189,8 +1213,7 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & I */ //============================================================================= -CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces) - throw (SALOME::SALOME_Exception) +SMESH::smIdType SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::smIdType_array & IdsOfFaces) { SMESH_TRY; initData(); @@ -1224,11 +1247,11 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_ar //============================================================================= // -// \brief Create 0D elements on all nodes of the given object except those -// nodes on which a 0D element already exists. +// \brief Create 0D elements on all nodes of the given object. // \param theObject object on whose nodes 0D elements will be created. // \param theGroupName optional name of a group to add 0D elements created // and/or found on nodes of \a theObject. +// \param DuplicateElements to add one more 0D element to a node or not. // \return an object (a new group or a temporary SMESH_IDSource) holding // ids of new and/or found 0D elements. // @@ -1236,8 +1259,8 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_ar SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject, - const char* theGroupName) - throw (SALOME::SALOME_Exception) + const char* theGroupName, + CORBA::Boolean theDuplicateElements) { SMESH_TRY; initData(); @@ -1246,11 +1269,10 @@ SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObje TPythonDump pyDump; TIDSortedElemSet elements, elems0D; - prepareIdSource( theObject ); if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) - getEditor().Create0DElementsOnAllNodes( elements, elems0D ); + getEditor().Create0DElementsOnAllNodes( elements, elems0D, theDuplicateElements ); - SMESH::long_array_var newElems = new SMESH::long_array; + SMESH::smIdType_array_var newElems = new SMESH::smIdType_array; newElems->length( elems0D.size() ); TIDSortedElemSet::iterator eIt = elems0D.begin(); for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt ) @@ -1307,8 +1329,7 @@ SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObje */ //============================================================================= -void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID) - throw (SALOME::SALOME_Exception) +void SMESH_MeshEditor_i::SetNodeOnVertex(SMESH::smIdType NodeID, CORBA::Long VertexID) { SMESH_TRY; @@ -1341,9 +1362,8 @@ void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexI */ //============================================================================= -void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID, +void SMESH_MeshEditor_i::SetNodeOnEdge(SMESH::smIdType NodeID, CORBA::Long EdgeID, CORBA::Double paramOnEdge) - throw (SALOME::SALOME_Exception) { SMESH_TRY; @@ -1362,8 +1382,11 @@ void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID, Standard_Real f,l; BRep_Tool::Range( TopoDS::Edge( shape ), f,l); if ( paramOnEdge < f || paramOnEdge > l ) - THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM); - + { + SMESH_Comment txt("Invalid paramOnEdge. It must vary in range [ "); + txt << f << ", " << l << " ]"; + THROW_SALOME_CORBA_EXCEPTION(txt.c_str(), SALOME::BAD_PARAM); + } mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge ); myMesh->SetIsModified( true ); @@ -1382,9 +1405,8 @@ void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID, */ //============================================================================= -void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID, +void SMESH_MeshEditor_i::SetNodeOnFace(SMESH::smIdType NodeID, CORBA::Long FaceID, CORBA::Double u, CORBA::Double v) - throw (SALOME::SALOME_Exception) { SMESH_TRY; SMESHDS_Mesh * mesh = getMeshDS(); @@ -1406,14 +1428,11 @@ void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID, v > surf.LastVParameter() ); if ( isOut ) { -#ifdef _DEBUG_ - MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of " - << " u( " << surf.FirstUParameter() - << "," << surf.LastUParameter() - << ") v( " << surf.FirstVParameter() - << "," << surf.LastVParameter() << ")" ); -#endif - THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM); + SMESH_Comment txt("Invalid UV. U must vary in range [ "); + txt << surf.FirstUParameter() << ", " << surf.LastUParameter() << " ], "; + txt << "V must vary in range [ "; + txt << surf.FirstVParameter() << ", " << surf.LastVParameter() << " ]"; + THROW_SALOME_CORBA_EXCEPTION(txt.c_str(), SALOME::BAD_PARAM); } mesh->SetNodeOnFace( node, FaceID, u, v ); @@ -1431,8 +1450,7 @@ void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID, */ //============================================================================= -void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID) - throw (SALOME::SALOME_Exception) +void SMESH_MeshEditor_i::SetNodeInVolume(SMESH::smIdType NodeID, CORBA::Long SolidID) { SMESH_TRY; SMESHDS_Mesh * mesh = getMeshDS(); @@ -1461,9 +1479,8 @@ void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID */ //============================================================================= -void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID, +void SMESH_MeshEditor_i::SetMeshElementOnShape(SMESH::smIdType ElementID, CORBA::Long ShapeID) - throw (SALOME::SALOME_Exception) { SMESH_TRY; SMESHDS_Mesh * mesh = getMeshDS(); @@ -1494,9 +1511,8 @@ void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID, */ //============================================================================= -CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1, - CORBA::Long NodeID2) - throw (SALOME::SALOME_Exception) +CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(SMESH::smIdType NodeID1, + SMESH::smIdType NodeID2) { SMESH_TRY; initData(); @@ -1525,9 +1541,8 @@ CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1, */ //============================================================================= -CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1, - CORBA::Long NodeID2) - throw (SALOME::SALOME_Exception) +CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(SMESH::smIdType NodeID1, + SMESH::smIdType NodeID2) { SMESH_TRY; initData(); @@ -1558,15 +1573,14 @@ CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1, */ //============================================================================= -CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements) - throw (SALOME::SALOME_Exception) +CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::smIdType_array & IDsOfElements) { SMESH_TRY; initData(); - for (int i = 0; i < IDsOfElements.length(); i++) + for ( SMESH::smIdType i = 0; i < IDsOfElements.length(); i++ ) { - CORBA::Long index = IDsOfElements[i]; + SMESH::smIdType index = IDsOfElements[i]; const SMDS_MeshElement * elem = getMeshDS()->FindElement(index); if ( elem ) getEditor().Reorient( elem ); @@ -1588,7 +1602,6 @@ CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfEleme //============================================================================= CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -1597,7 +1610,7 @@ CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theO prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); + SMESH::smIdType_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = Reorient(anElementsId); // Update Python script @@ -1625,14 +1638,16 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup, const SMESH::DirStruct& theDirection, CORBA::Long theFace, const SMESH::PointStruct& thePoint) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(/*deleteSearchers=*/false); TIDSortedElemSet elements; - prepareIdSource( the2Dgroup ); - if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1)) + IDSource_Error error; + idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error ); + if ( error == IDSource_EMPTY ) + return 0; + if ( error == IDSource_INVALID ) THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM); @@ -1698,23 +1713,79 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup, return 0; } +//======================================================================= +//function : Reorient2DBy3D +//purpose : Reorient faces basing on orientation of adjacent volumes. +//======================================================================= + +CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& faceGroups, + SMESH::SMESH_IDSource_ptr volumeGroup, + CORBA::Boolean outsideNormal) +{ + SMESH_TRY; + initData(); + + TIDSortedElemSet volumes; + IDSource_Error volsError; + idSourceToSet( volumeGroup, getMeshDS(), volumes, SMDSAbs_Volume, /*emptyIfMesh=*/1, &volsError); + + int nbReori = 0; + for ( size_t i = 0; i < faceGroups.length(); ++i ) + { + SMESH::SMESH_IDSource_ptr faceGrp = faceGroups[i].in(); + + TIDSortedElemSet faces; + IDSource_Error error; + idSourceToSet( faceGrp, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error ); + if ( error == IDSource_INVALID && faceGroups.length() == 1 ) + THROW_SALOME_CORBA_EXCEPTION("No faces in a given object", SALOME::BAD_PARAM); + if ( error == IDSource_OK && volsError != IDSource_OK ) + THROW_SALOME_CORBA_EXCEPTION("No volumes in a given object", SALOME::BAD_PARAM); + + nbReori += getEditor().Reorient2DBy3D( faces, volumes, outsideNormal ); + + if ( error != IDSource_EMPTY && faces.empty() ) // all faces in the mesh treated + break; + } + + if ( nbReori ) { + declareMeshModified( /*isReComputeSafe=*/false ); + } + TPythonDump() << this << ".Reorient2DBy3D( " + << faceGroups << ", " + << volumeGroup << ", " + << outsideNormal << " )"; + + return nbReori; + + SMESH_CATCH( SMESH::throwCorbaException ); + return 0; +} + //============================================================================= /*! * \brief Fuse neighbour triangles into quadrangles. */ //============================================================================= -CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements, +CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::smIdType_array & IDsOfElements, SMESH::NumericalFunctor_ptr Criterion, CORBA::Double MaxAngle) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); SMESHDS_Mesh* aMesh = getMeshDS(); - TIDSortedElemSet faces; - arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face); + TIDSortedElemSet faces,copyFaces; + SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE); + arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter); + TIDSortedElemSet* workElements = & faces; + + if ( myIsPreviewMode ) { + SMDSAbs_ElementType select = SMDSAbs_Face; + getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select ); + workElements = & copyFaces; + } SMESH::NumericalFunctor_i* aNumericalFunctor = dynamic_cast( SMESH_Gen_i::GetServant( Criterion ).in() ); @@ -1724,12 +1795,13 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfE else aCrit = aNumericalFunctor->GetNumericalFunctor(); - // Update Python script - TPythonDump() << "isDone = " << this << ".TriToQuad( " - << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )"; - + if ( !myIsPreviewMode ) { + // Update Python script + TPythonDump() << "isDone = " << this << ".TriToQuad( " + << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )"; + } - bool stat = getEditor().TriToQuad( faces, aCrit, MaxAngle ); + bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle ); declareMeshModified( /*isReComputeSafe=*/!stat ); return stat; @@ -1747,7 +1819,6 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfE CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject, SMESH::NumericalFunctor_ptr Criterion, CORBA::Double MaxAngle) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -1755,15 +1826,17 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr TPythonDump aTPythonDump; // suppress dump in TriToQuad() prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); + SMESH::smIdType_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle); - SMESH::NumericalFunctor_i* aNumericalFunctor = - SMESH::DownCast( Criterion ); + if ( !myIsPreviewMode ) { + SMESH::NumericalFunctor_i* aNumericalFunctor = + SMESH::DownCast( Criterion ); - // Update Python script - aTPythonDump << "isDone = " << this << ".TriToQuadObject(" - << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )"; + // Update Python script + aTPythonDump << "isDone = " << this << ".TriToQuadObject(" + << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )"; + } return isDone; @@ -1777,9 +1850,8 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr */ //============================================================================= -CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements, +CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::smIdType_array & IDsOfElements, SMESH::NumericalFunctor_ptr Criterion) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -1817,7 +1889,6 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfE CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject, SMESH::NumericalFunctor_ptr Criterion) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -1825,7 +1896,7 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr TPythonDump aTPythonDump; // suppress dump in QuadToTri() prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); + SMESH::smIdType_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion); SMESH::NumericalFunctor_i* aNumericalFunctor = @@ -1849,13 +1920,11 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr //================================================================================ void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); TIDSortedElemSet faces; - prepareIdSource( theObject ); if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) && faces.empty() ) THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM); @@ -1863,6 +1932,8 @@ void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject) getEditor().QuadTo4Tri( faces ); TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )"; + declareMeshModified( /*isReComputeSafe=*/false ); + SMESH_CATCH( SMESH::throwCorbaException ); } @@ -1872,9 +1943,8 @@ void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject) */ //============================================================================= -CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements, +CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::smIdType_array & IDsOfElements, CORBA::Boolean Diag13) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -1904,7 +1974,6 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfEle CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject, CORBA::Boolean Diag13) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -1912,7 +1981,7 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr th TPythonDump aTPythonDump; // suppress dump in SplitQuad() prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); + SMESH::smIdType_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13); // Update Python script @@ -1930,7 +1999,7 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr th //============================================================================= /*! * Find better splitting of the given quadrangle. - * \param IDOfQuad ID of the quadrangle to be splitted. + * \param IDOfQuad ID of the quadrangle to be split. * \param Criterion A criterion to choose a diagonal for splitting. * \return 1 if 1-3 diagonal is better, 2 if 2-4 * diagonal is better, 0 if error occurs. @@ -1939,7 +2008,6 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr th CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad, SMESH::NumericalFunctor_ptr Criterion) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -1957,6 +2025,7 @@ CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad, int id = getEditor().BestSplit(quad, aCrit); declareMeshModified( /*isReComputeSafe=*/ id < 1 ); + return id; } SMESH_CATCH( SMESH::throwCorbaException ); @@ -1971,17 +2040,18 @@ CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad, void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems, CORBA::Short methodFlags) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); + ::SMESH_MeshEditor::TFacetOfElem elemSet; + const int noneFacet = -1; prepareIdSource( elems ); - SMESH::long_array_var anElementsId = elems->GetIDs(); - TIDSortedElemSet elemSet; - arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume ); + if ( SMDS_ElemIteratorPtr volIt = myMesh_i->GetElements( elems, SMESH::VOLUME )) + while ( volIt->more() ) + elemSet.insert( elemSet.end(), make_pair( volIt->next(), noneFacet )); - getEditor().SplitVolumesIntoTetra( elemSet, int( methodFlags )); + getEditor().SplitVolumes( elemSet, int( methodFlags )); declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute() TPythonDump() << this << ".SplitVolumesIntoTetra( " @@ -1990,18 +2060,118 @@ void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems, SMESH_CATCH( SMESH::throwCorbaException ); } +//================================================================================ +/*! + * \brief Split hexahedra into triangular prisms + * \param elems - elements to split + * \param facetToSplitNormal - normal used to find a facet of hexahedron + * to split into triangles + * \param methodFlags - flags passing splitting method: + * 1 - split the hexahedron into 2 prisms + * 2 - split the hexahedron into 4 prisms + */ +//================================================================================ + +void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms( SMESH::SMESH_IDSource_ptr elems, + const SMESH::PointStruct & startHexPoint, + const SMESH::DirStruct& facetToSplitNormal, + CORBA::Short methodFlags, + CORBA::Boolean allDomains) +{ + SMESH_TRY; + initData(); + prepareIdSource( elems ); + + gp_Ax1 facetNorm( gp_Pnt( startHexPoint.x, + startHexPoint.y, + startHexPoint.z ), + gp_Dir( facetToSplitNormal.PS.x, + facetToSplitNormal.PS.y, + facetToSplitNormal.PS.z )); + TIDSortedElemSet elemSet; + prepareIdSource( elems ); + SMESH::smIdType_array_var anElementsId = elems->GetIDs(); + SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA ); + arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter ); + + ::SMESH_MeshEditor::TFacetOfElem elemFacets; + while ( !elemSet.empty() ) + { + getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets ); + if ( !allDomains ) + break; + + ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin(); + for ( ; ef != elemFacets.end(); ++ef ) + elemSet.erase( ef->first ); + } + + if ( methodFlags == 2 ) + methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS ); + else + methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS ); + + getEditor().SplitVolumes( elemFacets, int( methodFlags )); + declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute() + + TPythonDump() << this << ".SplitHexahedraIntoPrisms( " + << elems << ", " + << startHexPoint << ", " + << facetToSplitNormal<< ", " + << methodFlags<< ", " + << allDomains << " )"; + + SMESH_CATCH( SMESH::throwCorbaException ); +} + +//================================================================================ +/*! + * \brief Split bi-quadratic elements into linear ones without creation of additional nodes: + * - bi-quadratic triangle will be split into 3 linear quadrangles; + * - bi-quadratic quadrangle will be split into 4 linear quadrangles; + * - tri-quadratic hexahedron will be split into 8 linear hexahedra. + * Quadratic elements of lower dimension adjacent to the split bi-quadratic element + * will be split in order to keep the mesh conformal. + * \param elems - elements to split + */ +//================================================================================ + +void SMESH_MeshEditor_i::SplitBiQuadraticIntoLinear(const SMESH::ListOfIDSources& theElems) +{ + SMESH_TRY; + initData(); + + TIDSortedElemSet elemSet; + for ( size_t i = 0; i < theElems.length(); ++i ) + { + SMESH::SMESH_IDSource_ptr elems = theElems[i].in(); + SMESH::SMESH_Mesh_var mesh = elems->GetMesh(); + if ( mesh->GetId() != myMesh_i->GetId() ) + THROW_SALOME_CORBA_EXCEPTION("Wrong mesh of IDSource", SALOME::BAD_PARAM); + + idSourceToSet( elems, getMeshDS(), elemSet, SMDSAbs_All ); + } + getEditor().SplitBiQuadraticIntoLinear( elemSet ); + + declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute() + + TPythonDump() << this << ".SplitBiQuadraticIntoLinear( " + << theElems << " )"; + + SMESH_CATCH( SMESH::throwCorbaException ); +} + //======================================================================= //function : Smooth //purpose : //======================================================================= CORBA::Boolean -SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements, - const SMESH::long_array & IDsOfFixedNodes, - CORBA::Long MaxNbOfIterations, +SMESH_MeshEditor_i::Smooth(const SMESH::smIdType_array & IDsOfElements, + const SMESH::smIdType_array & IDsOfFixedNodes, + CORBA::Short MaxNbOfIterations, CORBA::Double MaxAspectRatio, SMESH::SMESH_MeshEditor::Smooth_Method Method) - throw (SALOME::SALOME_Exception) { return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method, false ); @@ -2014,12 +2184,11 @@ SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements, //======================================================================= CORBA::Boolean -SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements, - const SMESH::long_array & IDsOfFixedNodes, - CORBA::Long MaxNbOfIterations, +SMESH_MeshEditor_i::SmoothParametric(const SMESH::smIdType_array & IDsOfElements, + const SMESH::smIdType_array & IDsOfFixedNodes, + CORBA::Short MaxNbOfIterations, CORBA::Double MaxAspectRatio, SMESH::SMESH_MeshEditor::Smooth_Method Method) - throw (SALOME::SALOME_Exception) { return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method, true ); @@ -2033,11 +2202,10 @@ SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsO CORBA::Boolean SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::long_array & IDsOfFixedNodes, - CORBA::Long MaxNbOfIterations, + const SMESH::smIdType_array & IDsOfFixedNodes, + CORBA::Short MaxNbOfIterations, CORBA::Double MaxAspectRatio, SMESH::SMESH_MeshEditor::Smooth_Method Method) - throw (SALOME::SALOME_Exception) { return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method, false); @@ -2051,11 +2219,10 @@ SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObjec CORBA::Boolean SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::long_array & IDsOfFixedNodes, - CORBA::Long MaxNbOfIterations, + const SMESH::smIdType_array & IDsOfFixedNodes, + CORBA::Short MaxNbOfIterations, CORBA::Double MaxAspectRatio, SMESH::SMESH_MeshEditor::Smooth_Method Method) - throw (SALOME::SALOME_Exception) { return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method, true); @@ -2069,13 +2236,12 @@ SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr //============================================================================= CORBA::Boolean -SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements, - const SMESH::long_array & IDsOfFixedNodes, - CORBA::Long MaxNbOfIterations, +SMESH_MeshEditor_i::smooth(const SMESH::smIdType_array & IDsOfElements, + const SMESH::smIdType_array & IDsOfFixedNodes, + CORBA::Short MaxNbOfIterations, CORBA::Double MaxAspectRatio, SMESH::SMESH_MeshEditor::Smooth_Method Method, bool IsParametric) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -2086,8 +2252,8 @@ SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements, arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face); set fixedNodes; - for (int i = 0; i < IDsOfFixedNodes.length(); i++) { - CORBA::Long index = IDsOfFixedNodes[i]; + for ( SMESH::smIdType i = 0; i < IDsOfFixedNodes.length(); i++) { + SMESH::smIdType index = IDsOfFixedNodes[i]; const SMDS_MeshNode * node = aMesh->FindNode(index); if ( node ) fixedNodes.insert( node ); @@ -2124,12 +2290,11 @@ SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements, CORBA::Boolean SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::long_array & IDsOfFixedNodes, - CORBA::Long MaxNbOfIterations, + const SMESH::smIdType_array & IDsOfFixedNodes, + CORBA::Short MaxNbOfIterations, CORBA::Double MaxAspectRatio, SMESH::SMESH_MeshEditor::Smooth_Method Method, bool IsParametric) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -2137,7 +2302,7 @@ SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObjec TPythonDump aTPythonDump; // suppress dump in smooth() prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); + SMESH::smIdType_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method, IsParametric); @@ -2163,7 +2328,6 @@ SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObjec //============================================================================= void SMESH_MeshEditor_i::RenumberNodes() - throw (SALOME::SALOME_Exception) { SMESH_TRY; // Update Python script @@ -2181,7 +2345,6 @@ void SMESH_MeshEditor_i::RenumberNodes() //============================================================================= void SMESH_MeshEditor_i::RenumberElements() - throw (SALOME::SALOME_Exception) { SMESH_TRY; // Update Python script @@ -2199,7 +2362,6 @@ void SMESH_MeshEditor_i::RenumberElements() //======================================================================= SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list* groupIDs) - throw (SALOME::SALOME_Exception) { SMESH_TRY; if ( !groupIDs ) @@ -2212,1448 +2374,604 @@ SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list* groupID } //======================================================================= -//function : rotationSweep +//function : RotationSweepObjects //purpose : //======================================================================= SMESH::ListOfGroups* -SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements, - const SMESH::AxisStruct & theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance, - const bool theMakeGroups, - const SMDSAbs_ElementType theElementType) - throw (SALOME::SALOME_Exception) +SMESH_MeshEditor_i::RotationSweepObjects(const SMESH::ListOfIDSources & theNodes, + const SMESH::ListOfIDSources & theEdges, + const SMESH::ListOfIDSources & theFaces, + const SMESH::AxisStruct & theAxis, + CORBA::Double theAngleInRadians, + CORBA::Long theNbOfSteps, + CORBA::Double theTolerance, + const bool theMakeGroups) { SMESH_TRY; initData(); - TIDSortedElemSet inElements, copyElements; - arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType); + TIDSortedElemSet elemsNodes[2]; + for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) { + if ( SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE )) + while ( nIt->more() ) elemsNodes[1].insert( nIt->next() ); + } + for ( int i = 0, nb = theEdges.length(); i < nb; ++i ) + idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge ); + for ( int i = 0, nb = theFaces.length(); i < nb; ++i ) + idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face ); - TIDSortedElemSet* workElements = & inElements; + TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2]; bool makeWalls=true; if ( myIsPreviewMode ) { SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume; - getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid ); - workElements = & copyElements; - //makeWalls = false; + TPreviewMesh * tmpMesh = getPreviewMesh(); + tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid ); + tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid ); + workElements = & copyElements[0]; + //makeWalls = false; -- faces are needed for preview } + TPythonDump aPythonDump; // it is here to prevent dump of getGroups() + gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ), gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz )); ::SMESH_MeshEditor::PGroupIDs groupIds = - getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians, + getEditor().RotationSweep (workElements, Ax1, theAngleInRadians, theNbOfSteps, theTolerance, theMakeGroups, makeWalls); + SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0; + declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute() - return theMakeGroups ? getGroups(groupIds.get()) : 0; + if ( !myIsPreviewMode ) + { + dumpGroupsList( aPythonDump, aGroups ); + aPythonDump << this<< ".RotationSweepObjects( " + << theNodes << ", " + << theEdges << ", " + << theFaces << ", " + << theAxis << ", " + << TVar( theAngleInRadians ) << ", " + << TVar( theNbOfSteps ) << ", " + << TVar( theTolerance ) << ", " + << theMakeGroups << " )"; + } + else + { + getPreviewMesh()->Remove( SMDSAbs_Volume ); + } + + return aGroups ? aGroups : new SMESH::ListOfGroups; SMESH_CATCH( SMESH::throwCorbaException ); return 0; } -//======================================================================= -//function : RotationSweep -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements, - const SMESH::AxisStruct & theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) - throw (SALOME::SALOME_Exception) +namespace MeshEditor_I { - if ( !myIsPreviewMode ) { - TPythonDump() << this << ".RotationSweep( " - << theIDsOfElements << ", " - << theAxis << ", " - << TVar( theAngleInRadians ) << ", " - << TVar( theNbOfSteps ) << ", " - << TVar( theTolerance ) << " )"; - } - rotationSweep(theIDsOfElements, - theAxis, - theAngleInRadians, - theNbOfSteps, - theTolerance, - false); + /*! + * \brief Structure used to pass extrusion parameters to ::SMESH_MeshEditor + */ + struct ExtrusionParams : public ::SMESH_MeshEditor::ExtrusParam + { + bool myIsExtrusionByNormal; + + static int makeFlags( CORBA::Boolean MakeGroups, + CORBA::Boolean ScaleVariation = false, + CORBA::Boolean AngleVariation = false, + CORBA::Boolean ByAverageNormal = false, + CORBA::Boolean UseInputElemsOnly = false, + CORBA::Long Flags = 0, + CORBA::Boolean MakeBoundary = true ) + { + if ( MakeGroups ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS; + if ( ByAverageNormal ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BY_AVG_NORMAL; + if ( UseInputElemsOnly) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY; + if ( ScaleVariation ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_SCALE_LINEAR_VARIATION; + if ( AngleVariation ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_ANGLE_LINEAR_VARIATION; + if ( MakeBoundary ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BOUNDARY; + return Flags; + } + // standard params + ExtrusionParams(const SMESH::DirStruct & theDir, + CORBA::Long theNbOfSteps, + const SMESH::double_array & theScaleFactors, + CORBA::Boolean theScaleVariation, + const SMESH::double_array & theAngles, + CORBA::Boolean theAngleVariation, + const SMESH::double_array & theBasePoint, + CORBA::Boolean theMakeGroups): + ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x, + theDir.PS.y, + theDir.PS.z ), + theNbOfSteps, + toList( theScaleFactors ), + toList( theAngles ), + TBasePoint( theBasePoint ), + makeFlags( theMakeGroups, theScaleVariation, theAngleVariation )), + myIsExtrusionByNormal( false ) + { + } + // advanced params + ExtrusionParams(const SMESH::DirStruct & theDir, + CORBA::Long theNbOfSteps, + CORBA::Boolean theMakeGroups, + CORBA::Long theExtrFlags, + CORBA::Double theSewTolerance): + ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x, + theDir.PS.y, + theDir.PS.z ), + theNbOfSteps, + std::list(), + std::list(), + 0, + makeFlags( theMakeGroups, false, false, false, false, + theExtrFlags, false ), + theSewTolerance ), + myIsExtrusionByNormal( false ) + { + } + // params for extrusion by normal + ExtrusionParams(CORBA::Double theStepSize, + CORBA::Long theNbOfSteps, + CORBA::Short theDim, + CORBA::Boolean theByAverageNormal, + CORBA::Boolean theUseInputElemsOnly, + CORBA::Boolean theMakeGroups ): + ::SMESH_MeshEditor::ExtrusParam ( theStepSize, + theNbOfSteps, + makeFlags( theMakeGroups, false, false, + theByAverageNormal, theUseInputElemsOnly ), + theDim), + myIsExtrusionByNormal( true ) + { + } + + void SetNoGroups() + { + Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS); + } + + static std::list toList( const SMESH::double_array & theScaleFactors ) + { + std::list scales; + for ( CORBA::ULong i = 0; i < theScaleFactors.length(); ++i ) + scales.push_back( theScaleFactors[i] ); + return scales; + } + + private: + + // structure used to convert SMESH::double_array to gp_XYZ* + struct TBasePoint + { + gp_XYZ *pp, p; + TBasePoint( const SMESH::double_array & theBasePoint ) + { + pp = 0; + if ( theBasePoint.length() == 3 ) + { + p.SetCoord( theBasePoint[0], theBasePoint[1], theBasePoint[2] ); + pp = &p; + } + } + operator const gp_XYZ*() const { return pp; } + }; + }; } //======================================================================= -//function : RotationSweepMakeGroups -//purpose : +/*! + * \brief Generate dim+1 elements by extrusion of elements along vector + * \param [in] edges - edges to extrude: a list including groups, sub-meshes or a mesh + * \param [in] faces - faces to extrude: a list including groups, sub-meshes or a mesh + * \param [in] nodes - nodes to extrude: a list including groups, sub-meshes or a mesh + * \param [in] stepVector - vector giving direction and distance of an extrusion step + * \param [in] nbOfSteps - number of elements to generate from one element + * \param [in] toMakeGroups - if true, new elements will be included into new groups + * corresponding to groups the input elements included in. + * \return ListOfGroups - new groups created if \a toMakeGroups is true + */ //======================================================================= SMESH::ListOfGroups* -SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements, - const SMESH::AxisStruct& theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) - throw (SALOME::SALOME_Exception) +SMESH_MeshEditor_i::ExtrusionSweepObjects(const SMESH::ListOfIDSources & theNodes, + const SMESH::ListOfIDSources & theEdges, + const SMESH::ListOfIDSources & theFaces, + const SMESH::DirStruct & theStepVector, + CORBA::Long theNbOfSteps, + CORBA::Boolean theToMakeGroups, + const SMESH::double_array & theScaleFactors, + CORBA::Boolean theScalesVariation, + const SMESH::double_array & theBasePoint, + const SMESH::double_array & theAngles, + CORBA::Boolean theAnglesVariation) { - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements, - theAxis, - theAngleInRadians, - theNbOfSteps, - theTolerance, - true); - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".RotationSweepMakeGroups( " - << theIDsOfElements << ", " - << theAxis << ", " - << TVar( theAngleInRadians ) << ", " - << TVar( theNbOfSteps ) << ", " - << TVar( theTolerance ) << " )"; - } - return aGroups; -} - -//======================================================================= -//function : RotationSweepObject -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct & theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) - throw (SALOME::SALOME_Exception) -{ - if ( !myIsPreviewMode ) { - TPythonDump() << this << ".RotationSweepObject( " - << theObject << ", " - << theAxis << ", " - << theAngleInRadians << ", " - << theNbOfSteps << ", " - << theTolerance << " )"; - } - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - rotationSweep(anElementsId, - theAxis, - theAngleInRadians, - theNbOfSteps, - theTolerance, - false); -} - -//======================================================================= -//function : RotationSweepObject1D -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct & theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) - throw (SALOME::SALOME_Exception) -{ - if ( !myIsPreviewMode ) { - TPythonDump() << this << ".RotationSweepObject1D( " - << theObject << ", " - << theAxis << ", " - << TVar( theAngleInRadians ) << ", " - << TVar( theNbOfSteps ) << ", " - << TVar( theTolerance ) << " )"; - } - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - rotationSweep(anElementsId, - theAxis, - theAngleInRadians, - theNbOfSteps, - theTolerance, - false, - SMDSAbs_Edge); -} - -//======================================================================= -//function : RotationSweepObject2D -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct & theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) - throw (SALOME::SALOME_Exception) -{ - if ( !myIsPreviewMode ) { - TPythonDump() << this << ".RotationSweepObject2D( " - << theObject << ", " - << theAxis << ", " - << TVar( theAngleInRadians ) << ", " - << TVar( theNbOfSteps ) << ", " - << TVar( theTolerance ) << " )"; - } - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - rotationSweep(anElementsId, - theAxis, - theAngleInRadians, - theNbOfSteps, - theTolerance, - false, - SMDSAbs_Face); -} - -//======================================================================= -//function : RotationSweepObjectMakeGroups -//purpose : -//======================================================================= - -SMESH::ListOfGroups* -SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct& theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId, - theAxis, - theAngleInRadians, - theNbOfSteps, - theTolerance, - true); - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".RotationSweepObjectMakeGroups( " - << theObject << ", " - << theAxis << ", " - << theAngleInRadians << ", " - << theNbOfSteps << ", " - << theTolerance << " )"; - } - return aGroups; -} - -//======================================================================= -//function : RotationSweepObject1DMakeGroups -//purpose : -//======================================================================= - -SMESH::ListOfGroups* -SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct& theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId, - theAxis, - theAngleInRadians, - theNbOfSteps, - theTolerance, - true, - SMDSAbs_Edge); - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".RotationSweepObject1DMakeGroups( " - << theObject << ", " - << theAxis << ", " - << TVar( theAngleInRadians ) << ", " - << TVar( theNbOfSteps ) << ", " - << TVar( theTolerance ) << " )"; - } - return aGroups; -} - -//======================================================================= -//function : RotationSweepObject2DMakeGroups -//purpose : -//======================================================================= - -SMESH::ListOfGroups* -SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct& theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId, - theAxis, - theAngleInRadians, - theNbOfSteps, - theTolerance, - true, - SMDSAbs_Face); - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".RotationSweepObject2DMakeGroups( " - << theObject << ", " - << theAxis << ", " - << TVar( theAngleInRadians ) << ", " - << TVar( theNbOfSteps ) << ", " - << TVar( theTolerance ) << " )"; - } - return aGroups; -} + SMESH_TRY; + initData(); + ExtrusionParams params( theStepVector, theNbOfSteps, theScaleFactors, theScalesVariation, + theAngles, theAnglesVariation, theBasePoint, theToMakeGroups ); -//======================================================================= -//function : extrusionSweep -//purpose : -//======================================================================= - -SMESH::ListOfGroups* -SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements, - const SMESH::DirStruct & theStepVector, - CORBA::Long theNbOfSteps, - bool theMakeGroups, - const SMDSAbs_ElementType theElementType) - throw (SALOME::SALOME_Exception) -{ - SMESH_TRY; - initData(); - - TIDSortedElemSet elements, copyElements; - arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType); - - const SMESH::PointStruct * P = &theStepVector.PS; - gp_Vec stepVec( P->x, P->y, P->z ); - - TIDSortedElemSet* workElements = & elements; - - SMDSAbs_ElementType aType = SMDSAbs_Face; - if (theElementType == SMDSAbs_Node) - { - aType = SMDSAbs_Edge; - } - if ( myIsPreviewMode ) { - SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume; - getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid ); - workElements = & copyElements; - theMakeGroups = false; - } - - TElemOfElemListMap aHystory; - ::SMESH_MeshEditor::PGroupIDs groupIds = - getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups); - - declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute() - - return theMakeGroups ? getGroups(groupIds.get()) : 0; - - SMESH_CATCH( SMESH::throwCorbaException ); - return 0; -} - -//======================================================================= -//function : ExtrusionSweep -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements, - const SMESH::DirStruct & theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false ); - if (!myIsPreviewMode) { - TPythonDump() << this << ".ExtrusionSweep( " - << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )"; + TIDSortedElemSet elemsNodes[2]; + for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) { + if ( SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE )) + while ( nIt->more() ) elemsNodes[1].insert( nIt->next() ); } -} + for ( int i = 0, nb = theEdges.length(); i < nb; ++i ) + idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge ); + for ( int i = 0, nb = theFaces.length(); i < nb; ++i ) + idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face ); -//======================================================================= -//function : ExtrusionSweep0D -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements, - const SMESH::DirStruct & theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node ); - if (!myIsPreviewMode) { - TPythonDump() << this << ".ExtrusionSweep0D( " - << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )"; - } -} - -//======================================================================= -//function : ExtrusionSweepObject -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct & theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false ); - if (!myIsPreviewMode) { - TPythonDump() << this << ".ExtrusionSweepObject( " - << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )"; - } -} - -//======================================================================= -//function : ExtrusionSweepObject0D -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct & theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node ); - if ( !myIsPreviewMode ) { - TPythonDump() << this << ".ExtrusionSweepObject0D( " - << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; - } -} - -//======================================================================= -//function : ExtrusionSweepObject1D -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct & theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge ); - if ( !myIsPreviewMode ) { - TPythonDump() << this << ".ExtrusionSweepObject1D( " - << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; - } -} - -//======================================================================= -//function : ExtrusionSweepObject2D -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct & theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face ); - if ( !myIsPreviewMode ) { - TPythonDump() << this << ".ExtrusionSweepObject2D( " - << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; - } -} - -//======================================================================= -//function : ExtrusionSweepMakeGroups -//purpose : -//======================================================================= - -SMESH::ListOfGroups* -SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements, - const SMESH::DirStruct& theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true); - - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements - << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )"; - } - return aGroups; -} - -//======================================================================= -//function : ExtrusionSweepMakeGroups0D -//purpose : -//======================================================================= - -SMESH::ListOfGroups* -SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements, - const SMESH::DirStruct& theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node); - - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements - << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )"; - } - return aGroups; -} - -//======================================================================= -//function : ExtrusionSweepObjectMakeGroups -//purpose : -//======================================================================= - -SMESH::ListOfGroups* -SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct& theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true); - - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject - << ", " << theStepVector << ", " << theNbOfSteps << " )"; - } - return aGroups; -} - -//======================================================================= -//function : ExtrusionSweepObject0DMakeGroups -//purpose : -//======================================================================= - -SMESH::ListOfGroups* -SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct& theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, - theNbOfSteps, true, SMDSAbs_Node); - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject - << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; - } - return aGroups; -} - -//======================================================================= -//function : ExtrusionSweepObject1DMakeGroups -//purpose : -//======================================================================= - -SMESH::ListOfGroups* -SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct& theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, - theNbOfSteps, true, SMDSAbs_Edge); - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject - << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; - } - return aGroups; -} - -//======================================================================= -//function : ExtrusionSweepObject2DMakeGroups -//purpose : -//======================================================================= - -SMESH::ListOfGroups* -SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct& theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, - theNbOfSteps, true, SMDSAbs_Face); - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject - << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; - } - return aGroups; -} - - -//======================================================================= -//function : advancedExtrusion -//purpose : -//======================================================================= - -SMESH::ListOfGroups* -SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements, - const SMESH::DirStruct & theStepVector, - CORBA::Long theNbOfSteps, - CORBA::Long theExtrFlags, - CORBA::Double theSewTolerance, - const bool theMakeGroups) - throw (SALOME::SALOME_Exception) -{ - SMESH_TRY; - initData(); - - TIDSortedElemSet elements; - arrayToSet(theIDsOfElements, getMeshDS(), elements); - - const SMESH::PointStruct * P = &theStepVector.PS; - gp_Vec stepVec( P->x, P->y, P->z ); - - TElemOfElemListMap aHystory; - ::SMESH_MeshEditor::PGroupIDs groupIds = - getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory, - theMakeGroups, theExtrFlags, theSewTolerance); - - declareMeshModified( /*isReComputeSafe=*/true ); - - return theMakeGroups ? getGroups(groupIds.get()) : 0; - - SMESH_CATCH( SMESH::throwCorbaException ); - return 0; -} - -//======================================================================= -//function : AdvancedExtrusion -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements, - const SMESH::DirStruct & theStepVector, - CORBA::Long theNbOfSteps, - CORBA::Long theExtrFlags, - CORBA::Double theSewTolerance) - throw (SALOME::SALOME_Exception) -{ - if ( !myIsPreviewMode ) { - TPythonDump() << "stepVector = " << theStepVector; - TPythonDump() << this << ".AdvancedExtrusion(" - << theIDsOfElements - << ", stepVector, " - << theNbOfSteps << "," - << theExtrFlags << ", " - << theSewTolerance << " )"; - } - advancedExtrusion( theIDsOfElements, - theStepVector, - theNbOfSteps, - theExtrFlags, - theSewTolerance, - false); -} - -//======================================================================= -//function : AdvancedExtrusionMakeGroups -//purpose : -//======================================================================= -SMESH::ListOfGroups* -SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements, - const SMESH::DirStruct& theStepVector, - CORBA::Long theNbOfSteps, - CORBA::Long theExtrFlags, - CORBA::Double theSewTolerance) - throw (SALOME::SALOME_Exception) -{ - if (!myIsPreviewMode) { - TPythonDump() << "stepVector = " << theStepVector; - } - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements, - theStepVector, - theNbOfSteps, - theExtrFlags, - theSewTolerance, - true); - - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".AdvancedExtrusionMakeGroups(" - << theIDsOfElements - << ", stepVector, " - << theNbOfSteps << "," - << theExtrFlags << ", " - << theSewTolerance << " )"; - } - return aGroups; -} - - -//================================================================================ -/*! - * \brief Convert extrusion error to IDL enum - */ -//================================================================================ - -#define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm; - -static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e ) -{ - switch ( e ) { - RETCASE( EXTR_OK ); - RETCASE( EXTR_NO_ELEMENTS ); - RETCASE( EXTR_PATH_NOT_EDGE ); - RETCASE( EXTR_BAD_PATH_SHAPE ); - RETCASE( EXTR_BAD_STARTING_NODE ); - RETCASE( EXTR_BAD_ANGLES_NUMBER ); - RETCASE( EXTR_CANT_GET_TANGENT ); - } - return SMESH::SMESH_MeshEditor::EXTR_OK; -} - - -//======================================================================= -//function : extrusionAlongPath -//purpose : -//======================================================================= -SMESH::ListOfGroups* -SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array & theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct & theRefPoint, - const bool theMakeGroups, - SMESH::SMESH_MeshEditor::Extrusion_Error & theError, - const SMDSAbs_ElementType theElementType) - throw (SALOME::SALOME_Exception) -{ - SMESH_TRY; - MESSAGE("extrusionAlongPath"); - initData(); - - if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) { - theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE; - return 0; - } - SMESH_Mesh_i* aMeshImp = SMESH::DownCast( thePathMesh ); - - TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape ); - SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape ); - - if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) { - theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE; - return 0; - } - - SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart); - if ( !nodeStart ) { - theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE; - return 0; - } + TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2]; + SMDSAbs_ElementType previewType = SMDSAbs_All; //SMDSAbs_Face; + if ( myIsPreviewMode ) + { + // if ( (*elemsNodes.begin())->GetType() == SMDSAbs_Node ) + // previewType = SMDSAbs_Edge; - TIDSortedElemSet elements; - arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType); + SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume; + TPreviewMesh * tmpMesh = getPreviewMesh( previewType ); + tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid ); + tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid ); + workElements = & copyElements[0]; - list angles; - for (int i = 0; i < theAngles.length(); i++) { - angles.push_back( theAngles[i] ); + params.SetNoGroups(); } + TPythonDump aPythonDump; // it is here to prevent dump of getGroups() - gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z ); - - int nbOldGroups = myMesh->NbGroup(); + ::SMESH_MeshEditor::TTElemOfElemListMap aHistory; + ::SMESH_MeshEditor::PGroupIDs groupIds = + getEditor().ExtrusionSweep( workElements, params, aHistory ); - ::SMESH_MeshEditor::Extrusion_Error error = - getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart, - theHasAngles, angles, false, - theHasRefPoint, refPnt, theMakeGroups ); + SMESH::ListOfGroups * aGroups = theToMakeGroups ? getGroups( groupIds.get()) : 0; - declareMeshModified( /*isReComputeSafe=*/true ); - theError = convExtrError( error ); + declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute() - if ( theMakeGroups ) { - list groupIDs = myMesh->GetGroupIds(); - list::iterator newBegin = groupIDs.begin(); - std::advance( newBegin, nbOldGroups ); // skip old groups - groupIDs.erase( groupIDs.begin(), newBegin ); - return getGroups( & groupIDs ); + if ( !myIsPreviewMode ) + { + dumpGroupsList( aPythonDump, aGroups ); + aPythonDump << this<< ".ExtrusionSweepObjects( " + << theNodes << ", " + << theEdges << ", " + << theFaces << ", " + << theStepVector << ", " + << TVar( theNbOfSteps ) << ", " + << theToMakeGroups << ", " + << TVar( theScaleFactors ) << ", " + << theScalesVariation << ", " + << TVar( theBasePoint ) << ", " + << TVar( theAngles ) << ", " + << theAnglesVariation << " )"; } - return 0; + else + { + getPreviewMesh( previewType )->Remove( SMDSAbs_Volume ); + } + + return aGroups ? aGroups : new SMESH::ListOfGroups; SMESH_CATCH( SMESH::throwCorbaException ); return 0; } //======================================================================= -//function : extrusionAlongPathX +//function : ExtrusionByNormal //purpose : //======================================================================= SMESH::ListOfGroups* -SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements, - SMESH::SMESH_IDSource_ptr Path, - CORBA::Long NodeStart, - CORBA::Boolean HasAngles, - const SMESH::double_array& Angles, - CORBA::Boolean LinearVariation, - CORBA::Boolean HasRefPoint, - const SMESH::PointStruct& RefPoint, - bool MakeGroups, - const SMDSAbs_ElementType ElementType, - SMESH::SMESH_MeshEditor::Extrusion_Error & Error) - throw (SALOME::SALOME_Exception) +SMESH_MeshEditor_i::ExtrusionByNormal(const SMESH::ListOfIDSources& objects, + CORBA::Double stepSize, + CORBA::Long nbOfSteps, + CORBA::Boolean byAverageNormal, + CORBA::Boolean useInputElemsOnly, + CORBA::Boolean makeGroups, + CORBA::Short dim) { SMESH_TRY; - SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups; - initData(); - list angles; - for (int i = 0; i < Angles.length(); i++) { - angles.push_back( Angles[i] ); - } - gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z ); - int nbOldGroups = myMesh->NbGroup(); + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - if ( Path->_is_nil() ) { - Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE; - return EmptyGr; - } + ExtrusionParams params( stepSize, nbOfSteps, dim, + byAverageNormal, useInputElemsOnly, makeGroups ); - TIDSortedElemSet elements, copyElements; - arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType); + SMDSAbs_ElementType elemType = ( dim == 1 ? SMDSAbs_Edge : SMDSAbs_Face ); + if ( objects.length() > 0 && !SMESH::DownCast( objects[0] )) + { + SMESH::array_of_ElementType_var elemTypes = objects[0]->GetTypes(); + if (( elemTypes->length() == 1 ) && + ( elemTypes[0] == SMESH::EDGE || elemTypes[0] == SMESH::FACE )) + elemType = ( SMDSAbs_ElementType ) elemTypes[0]; + } - TIDSortedElemSet* workElements = &elements; + TIDSortedElemSet elemsNodes[2]; + for ( int i = 0, nb = objects.length(); i < nb; ++i ) + idSourceToSet( objects[i], getMeshDS(), elemsNodes[0], elemType ); + TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2]; + SMDSAbs_ElementType previewType = SMDSAbs_Face; if ( myIsPreviewMode ) { SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume; - getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid ); - workElements = & copyElements; - MakeGroups = false; + TPreviewMesh * tmpMesh = getPreviewMesh( previewType ); + tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid ); + workElements = & copyElements[0]; + + params.SetNoGroups(); } - ::SMESH_MeshEditor::Extrusion_Error error; + ::SMESH_MeshEditor::TTElemOfElemListMap aHistory; + ::SMESH_MeshEditor::PGroupIDs groupIds = + getEditor().ExtrusionSweep( workElements, params, aHistory ); - if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast( Path )) - { - // path as mesh - SMDS_MeshNode* aNodeStart = - (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart); - if ( !aNodeStart ) { - Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE; - return EmptyGr; - } - error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart, - HasAngles, angles, LinearVariation, - HasRefPoint, refPnt, MakeGroups ); - declareMeshModified( /*isReComputeSafe=*/true ); - } - else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast( Path )) - { - // path as submesh - SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather(); - aMeshImp = SMESH::DownCast( aPathMesh ); - SMDS_MeshNode* aNodeStart = - (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart); - if ( !aNodeStart ) { - Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE; - return EmptyGr; - } - SMESH_subMesh* aSubMesh = - aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId()); - error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart, - HasAngles, angles, LinearVariation, - HasRefPoint, refPnt, MakeGroups ); - declareMeshModified( /*isReComputeSafe=*/true ); - } - else if ( SMESH::DownCast( Path )) - { - // path as group of 1D elements - // ???????? + SMESH::ListOfGroups * aGroups = makeGroups ? getGroups( groupIds.get()) : 0; + + if (!myIsPreviewMode) { + dumpGroupsList(aPythonDump, aGroups); + aPythonDump << this << ".ExtrusionByNormal( " << objects + << ", " << TVar( stepSize ) + << ", " << TVar( nbOfSteps ) + << ", " << byAverageNormal + << ", " << useInputElemsOnly + << ", " << makeGroups + << ", " << dim + << " )"; } else { - // invalid path - Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE; - return EmptyGr; + getPreviewMesh( previewType )->Remove( SMDSAbs_Volume ); } - Error = convExtrError( error ); + declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute() - if ( MakeGroups ) { - list groupIDs = myMesh->GetGroupIds(); - list::iterator newBegin = groupIDs.begin(); - std::advance( newBegin, nbOldGroups ); // skip old groups - groupIDs.erase( groupIDs.begin(), newBegin ); - return getGroups( & groupIDs ); - } - return EmptyGr; + return aGroups ? aGroups : new SMESH::ListOfGroups; SMESH_CATCH( SMESH::throwCorbaException ); return 0; } //======================================================================= -//function : ExtrusionAlongPath +//function : AdvancedExtrusion //purpose : //======================================================================= -SMESH::SMESH_MeshEditor::Extrusion_Error -SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array & theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct & theRefPoint) - throw (SALOME::SALOME_Exception) +SMESH::ListOfGroups* +SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::smIdType_array & theIDsOfElements, + const SMESH::DirStruct & theStepVector, + CORBA::Long theNbOfSteps, + CORBA::Long theExtrFlags, + CORBA::Double theSewTolerance, + CORBA::Boolean theMakeGroups) { - MESSAGE("ExtrusionAlongPath"); - if ( !myIsPreviewMode ) { - TPythonDump() << "error = " << this << ".ExtrusionAlongPath( " - << theIDsOfElements << ", " - << thePathMesh << ", " - << thePathShape << ", " - << theNodeStart << ", " - << theHasAngles << ", " - << theAngles << ", " - << theHasRefPoint << ", " - << "SMESH.PointStruct( " - << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )"; - } - SMESH::SMESH_MeshEditor::Extrusion_Error anError; - extrusionAlongPath( theIDsOfElements, - thePathMesh, - thePathShape, - theNodeStart, - theHasAngles, - theAngles, - theHasRefPoint, - theRefPoint, - false, - anError); - return anError; -} - -//======================================================================= -//function : ExtrusionAlongPathObject -//purpose : -//======================================================================= + SMESH_TRY; + initData(); -SMESH::SMESH_MeshEditor::Extrusion_Error -SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array & theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct & theRefPoint) - throw (SALOME::SALOME_Exception) -{ - if ( !myIsPreviewMode ) { - TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( " - << theObject << ", " - << thePathMesh << ", " - << thePathShape << ", " - << theNodeStart << ", " - << theHasAngles << ", " - << theAngles << ", " - << theHasRefPoint << ", " - << "SMESH.PointStruct( " - << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )"; - } - SMESH::SMESH_MeshEditor::Extrusion_Error anError; - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - extrusionAlongPath( anElementsId, - thePathMesh, - thePathShape, - theNodeStart, - theHasAngles, - theAngles, - theHasRefPoint, - theRefPoint, - false, - anError); - return anError; -} - -//======================================================================= -//function : ExtrusionAlongPathObject1D -//purpose : -//======================================================================= + TPythonDump aPythonDump; // it is here to prevent dump of getGroups() -SMESH::SMESH_MeshEditor::Extrusion_Error -SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array & theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct & theRefPoint) - throw (SALOME::SALOME_Exception) -{ - if ( !myIsPreviewMode ) { - TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( " - << theObject << ", " - << thePathMesh << ", " - << thePathShape << ", " - << theNodeStart << ", " - << theHasAngles << ", " - << theAngles << ", " - << theHasRefPoint << ", " - << "SMESH.PointStruct( " - << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )"; - } - SMESH::SMESH_MeshEditor::Extrusion_Error anError; - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - extrusionAlongPath( anElementsId, - thePathMesh, - thePathShape, - theNodeStart, - theHasAngles, - theAngles, - theHasRefPoint, - theRefPoint, - false, - anError, - SMDSAbs_Edge); - return anError; -} - -//======================================================================= -//function : ExtrusionAlongPathObject2D -//purpose : -//======================================================================= + ExtrusionParams params( theStepVector, theNbOfSteps, theMakeGroups, + theExtrFlags, theSewTolerance ); -SMESH::SMESH_MeshEditor::Extrusion_Error -SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array & theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct & theRefPoint) - throw (SALOME::SALOME_Exception) -{ - if ( !myIsPreviewMode ) { - TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( " - << theObject << ", " - << thePathMesh << ", " - << thePathShape << ", " - << theNodeStart << ", " - << theHasAngles << ", " - << theAngles << ", " - << theHasRefPoint << ", " - << "SMESH.PointStruct( " - << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )"; - } - SMESH::SMESH_MeshEditor::Extrusion_Error anError; - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - extrusionAlongPath( anElementsId, - thePathMesh, - thePathShape, - theNodeStart, - theHasAngles, - theAngles, - theHasRefPoint, - theRefPoint, - false, - anError, - SMDSAbs_Face); - return anError; -} + TIDSortedElemSet elemsNodes[2]; + arrayToSet( theIDsOfElements, getMeshDS(), elemsNodes[0] ); + ::SMESH_MeshEditor::TTElemOfElemListMap aHistory; + ::SMESH_MeshEditor::PGroupIDs groupIds = + getEditor().ExtrusionSweep( elemsNodes, params, aHistory ); -//======================================================================= -//function : ExtrusionAlongPathMakeGroups -//purpose : -//======================================================================= + SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0; -SMESH::ListOfGroups* -SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array& theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct& theRefPoint, - SMESH::SMESH_MeshEditor::Extrusion_Error& Error) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute() - SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements, - thePathMesh, - thePathShape, - theNodeStart, - theHasAngles, - theAngles, - theHasRefPoint, - theRefPoint, - true, - Error); - if (!myIsPreviewMode) { - bool isDumpGroups = aGroups && aGroups->length() > 0; - if (isDumpGroups) - aPythonDump << "(" << aGroups << ", error)"; - else - aPythonDump <<"error"; - - aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( " - << theIDsOfElements << ", " - << thePathMesh << ", " - << thePathShape << ", " - << theNodeStart << ", " - << theHasAngles << ", " - << theAngles << ", " - << theHasRefPoint << ", " - << "SMESH.PointStruct( " - << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )"; + if ( !myIsPreviewMode ) { + dumpGroupsList(aPythonDump, aGroups); + aPythonDump << this << ".AdvancedExtrusion( " + << theIDsOfElements << ", " + << theStepVector << ", " + << theNbOfSteps << ", " + << theExtrFlags << ", " + << theSewTolerance << ", " + << theMakeGroups << " )"; + } + else + { + getPreviewMesh()->Remove( SMDSAbs_Volume ); } - return aGroups; -} -//======================================================================= -//function : ExtrusionAlongPathObjectMakeGroups -//purpose : -//======================================================================= + return aGroups ? aGroups : new SMESH::ListOfGroups; -SMESH::ListOfGroups* SMESH_MeshEditor_i:: -ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array& theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct& theRefPoint, - SMESH::SMESH_MeshEditor::Extrusion_Error& Error) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + SMESH_CATCH( SMESH::throwCorbaException ); + return 0; +} - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId, - thePathMesh, - thePathShape, - theNodeStart, - theHasAngles, - theAngles, - theHasRefPoint, - theRefPoint, - true, - Error); +//================================================================================ +/*! + * \brief Convert extrusion error to IDL enum + */ +//================================================================================ - if (!myIsPreviewMode) { - bool isDumpGroups = aGroups && aGroups->length() > 0; - if (isDumpGroups) - aPythonDump << "(" << aGroups << ", error)"; - else - aPythonDump <<"error"; +namespace +{ +#define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm; - aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( " - << theObject << ", " - << thePathMesh << ", " - << thePathShape << ", " - << theNodeStart << ", " - << theHasAngles << ", " - << theAngles << ", " - << theHasRefPoint << ", " - << "SMESH.PointStruct( " - << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )"; + SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( ::SMESH_MeshEditor::Extrusion_Error e ) + { + switch ( e ) { + RETCASE( EXTR_OK ); + RETCASE( EXTR_NO_ELEMENTS ); + RETCASE( EXTR_PATH_NOT_EDGE ); + RETCASE( EXTR_BAD_PATH_SHAPE ); + RETCASE( EXTR_BAD_STARTING_NODE ); + RETCASE( EXTR_BAD_ANGLES_NUMBER ); + RETCASE( EXTR_CANT_GET_TANGENT ); + } + return SMESH::SMESH_MeshEditor::EXTR_OK; } - return aGroups; } //======================================================================= -//function : ExtrusionAlongPathObject1DMakeGroups +//function : extrusionAlongPath //purpose : //======================================================================= - -SMESH::ListOfGroups* SMESH_MeshEditor_i:: -ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array& theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct& theRefPoint, - SMESH::SMESH_MeshEditor::Extrusion_Error& Error) - throw (SALOME::SALOME_Exception) +SMESH::ListOfGroups* +SMESH_MeshEditor_i::ExtrusionAlongPathObjects(const SMESH::ListOfIDSources & theNodes, + const SMESH::ListOfIDSources & theEdges, + const SMESH::ListOfIDSources & theFaces, + SMESH::SMESH_IDSource_ptr thePathObject, + GEOM::GEOM_Object_ptr thePathShape, + SMESH::smIdType theNodeStart, + CORBA::Boolean theHasAngles, + const SMESH::double_array & theAngles, + CORBA::Boolean theAnglesVariation, + CORBA::Boolean theHasRefPoint, + const SMESH::PointStruct & theRefPoint, + bool theMakeGroups, + const SMESH::double_array & theScaleFactors, + CORBA::Boolean theScalesVariation, + SMESH::SMESH_MeshEditor::Extrusion_Error& theError) { - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + SMESH_TRY; + initData(); - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId, - thePathMesh, - thePathShape, - theNodeStart, - theHasAngles, - theAngles, - theHasRefPoint, - theRefPoint, - true, - Error, - SMDSAbs_Edge); + SMESH::ListOfGroups_var aGroups = new SMESH::ListOfGroups; - if (!myIsPreviewMode) { - bool isDumpGroups = aGroups && aGroups->length() > 0; - if (isDumpGroups) - aPythonDump << "(" << aGroups << ", error)"; - else - aPythonDump << "error"; + theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE; + if ( thePathObject->_is_nil() ) + return aGroups._retn(); - aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( " - << theObject << ", " - << thePathMesh << ", " - << thePathShape << ", " - << theNodeStart << ", " - << theHasAngles << ", " - << theAngles << ", " - << theHasRefPoint << ", " - << "SMESH.PointStruct( " - << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )"; + + SMDS_ElemIteratorPtr pathEdgesIterator; + + SMESH_Mesh_i* aMeshImp = SMESH::DownCast( thePathObject ); + if ( !CORBA::is_nil( thePathShape ) && aMeshImp ) + { + // get a sub-mesh of thePathShape + TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape ); + SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape ); + if ( !aSubMesh ) + return aGroups._retn(); + + if ( !aSubMesh->GetSubMeshDS() ) + { + SMESHDS_Mesh * meshDS = aMeshImp->GetImpl().GetMeshDS(); + meshDS->AddCompoundSubmesh( aShape, TopAbs_EDGE ); + if ( !aSubMesh->GetSubMeshDS() ) + return aGroups._retn(); + } + theError = SMESH::SMESH_MeshEditor::EXTR_PATH_NOT_EDGE; + pathEdgesIterator = aSubMesh->GetSubMeshDS()->GetElements(); + if ( !pathEdgesIterator->more() || + pathEdgesIterator->next()->GetType() != SMDSAbs_Edge ) + return aGroups._retn(); + + pathEdgesIterator = aSubMesh->GetSubMeshDS()->GetElements(); + } + else + { + theError = SMESH::SMESH_MeshEditor::EXTR_PATH_NOT_EDGE; + prepareIdSource( thePathObject ); + pathEdgesIterator = SMESH_Mesh_i::GetElements( thePathObject, SMESH::EDGE ); + if ( !pathEdgesIterator || !pathEdgesIterator->more() ) + return aGroups._retn(); } - return aGroups; -} -//======================================================================= -//function : ExtrusionAlongPathObject2DMakeGroups -//purpose : -//======================================================================= + if ( !aMeshImp ) + { + SMESH::SMESH_Mesh_var pathMesh = thePathObject->GetMesh(); + aMeshImp = SMESH::DownCast( pathMesh ); + } -SMESH::ListOfGroups* SMESH_MeshEditor_i:: -ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array& theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct& theRefPoint, - SMESH::SMESH_MeshEditor::Extrusion_Error& Error) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId, - thePathMesh, - thePathShape, - theNodeStart, - theHasAngles, - theAngles, - theHasRefPoint, - theRefPoint, - true, - Error, - SMDSAbs_Face); + theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE; + const SMDS_MeshNode* nodeStart = aMeshImp->GetImpl().GetMeshDS()->FindNode( theNodeStart ); + if ( !nodeStart ) + return aGroups._retn(); - if (!myIsPreviewMode) { - bool isDumpGroups = aGroups && aGroups->length() > 0; - if (isDumpGroups) - aPythonDump << "(" << aGroups << ", error)"; - else - aPythonDump << "error"; - aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( " - << theObject << ", " - << thePathMesh << ", " - << thePathShape << ", " - << theNodeStart << ", " - << theHasAngles << ", " - << theAngles << ", " - << theHasRefPoint << ", " - << "SMESH.PointStruct( " - << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )"; + TIDSortedElemSet elemsNodes[2]; + for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) { + if ( SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE )) + while ( nIt->more() ) elemsNodes[1].insert( nIt->next() ); } - return aGroups; -} + for ( int i = 0, nb = theEdges.length(); i < nb; ++i ) + idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge ); + for ( int i = 0, nb = theFaces.length(); i < nb; ++i ) + idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face ); -//======================================================================= -//function : ExtrusionAlongPathObjX -//purpose : -//======================================================================= + list angles = ExtrusionParams::toList( theAngles ); + list scales = ExtrusionParams::toList( theScaleFactors ); -SMESH::ListOfGroups* SMESH_MeshEditor_i:: -ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object, - SMESH::SMESH_IDSource_ptr Path, - CORBA::Long NodeStart, - CORBA::Boolean HasAngles, - const SMESH::double_array& Angles, - CORBA::Boolean LinearVariation, - CORBA::Boolean HasRefPoint, - const SMESH::PointStruct& RefPoint, - CORBA::Boolean MakeGroups, - SMESH::ElementType ElemType, - SMESH::SMESH_MeshEditor::Extrusion_Error& Error) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z ); + const gp_Pnt *refPntPtr = theHasRefPoint ? &refPnt : 0; - prepareIdSource( Object ); - SMESH::long_array_var anElementsId = Object->GetIDs(); - SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId, - Path, - NodeStart, - HasAngles, - Angles, - LinearVariation, - HasRefPoint, - RefPoint, - MakeGroups, - (SMDSAbs_ElementType)ElemType, - Error); + int nbOldGroups = myMesh->NbGroup(); - if (!myIsPreviewMode) { - bool isDumpGroups = aGroups && aGroups->length() > 0; - if (isDumpGroups) - aPythonDump << "(" << *aGroups << ", error)"; - else - aPythonDump << "error"; - - aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( " - << Object << ", " - << Path << ", " - << NodeStart << ", " - << HasAngles << ", " - << TVar( Angles ) << ", " - << LinearVariation << ", " - << HasRefPoint << ", " - << "SMESH.PointStruct( " - << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", " - << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", " - << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), " - << MakeGroups << ", " - << ElemType << " )"; + TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2]; + if ( myIsPreviewMode ) + { + SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume; + TPreviewMesh * tmpMesh = getPreviewMesh(); + tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid ); + tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid ); + workElements = & copyElements[0]; + theMakeGroups = false; } - return aGroups; -} -//======================================================================= -//function : ExtrusionAlongPathX -//purpose : -//======================================================================= + ::SMESH_MeshEditor::Extrusion_Error error = + getEditor().ExtrusionAlongTrack( workElements, + &(aMeshImp->GetImpl()), pathEdgesIterator, nodeStart, + angles, theAnglesVariation, + scales, theScalesVariation, + refPntPtr, theMakeGroups ); -SMESH::ListOfGroups* SMESH_MeshEditor_i:: -ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements, - SMESH::SMESH_IDSource_ptr Path, - CORBA::Long NodeStart, - CORBA::Boolean HasAngles, - const SMESH::double_array& Angles, - CORBA::Boolean LinearVariation, - CORBA::Boolean HasRefPoint, - const SMESH::PointStruct& RefPoint, - CORBA::Boolean MakeGroups, - SMESH::ElementType ElemType, - SMESH::SMESH_MeshEditor::Extrusion_Error& Error) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + declareMeshModified( /*isReComputeSafe=*/true ); + theError = convExtrError( error ); - SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements, - Path, - NodeStart, - HasAngles, - Angles, - LinearVariation, - HasRefPoint, - RefPoint, - MakeGroups, - (SMDSAbs_ElementType)ElemType, - Error); + TPythonDump aPythonDump; // it is here to prevent dump of getGroups() + if ( theMakeGroups ) { + list groupIDs = myMesh->GetGroupIds(); + list::iterator newBegin = groupIDs.begin(); + std::advance( newBegin, nbOldGroups ); // skip old groups + groupIDs.erase( groupIDs.begin(), newBegin ); + aGroups = getGroups( & groupIDs ); + if ( ! &aGroups.in() ) aGroups = new SMESH::ListOfGroups; + } - if (!myIsPreviewMode) { - bool isDumpGroups = aGroups && aGroups->length() > 0; - if (isDumpGroups) - aPythonDump << "(" << *aGroups << ", error)"; - else - aPythonDump <<"error"; - - aPythonDump << " = " << this << ".ExtrusionAlongPathX( " - << IDsOfElements << ", " - << Path << ", " - << NodeStart << ", " - << HasAngles << ", " - << TVar( Angles ) << ", " - << LinearVariation << ", " - << HasRefPoint << ", " + if ( !myIsPreviewMode ) { + if ( aGroups->length() > 0 ) aPythonDump << "(" << aGroups << ", error) = "; + else aPythonDump << "(_noGroups, error) = "; + aPythonDump << this << ".ExtrusionAlongPathObjects( " + << theNodes << ", " + << theEdges << ", " + << theFaces << ", " + << thePathObject << ", " + << thePathShape << ", " + << theNodeStart << ", " + << theHasAngles << ", " + << TVar( theAngles ) << ", " + << theAnglesVariation << ", " + << theHasRefPoint << ", " << "SMESH.PointStruct( " - << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", " - << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", " - << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), " - << MakeGroups << ", " - << ElemType << " )"; + << TVar( theHasRefPoint ? theRefPoint.x : 0 ) << ", " + << TVar( theHasRefPoint ? theRefPoint.y : 0 ) << ", " + << TVar( theHasRefPoint ? theRefPoint.z : 0 ) << " ), " + << theMakeGroups << ", " + << TVar( theScaleFactors ) << ", " + << theScalesVariation << " )"; } - return aGroups; + else + { + getPreviewMesh()->Remove( SMDSAbs_Volume ); + } + + return aGroups._retn(); + + SMESH_CATCH( SMESH::throwCorbaException ); + return 0; } //================================================================================ @@ -3681,7 +2999,7 @@ SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMes SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape ); if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) return aResult._retn(); - int nbSteps = aSubMesh->GetSubMeshDS()->NbElements(); + smIdType nbSteps = aSubMesh->GetSubMeshDS()->NbElements(); if ( nbSteps == nbAngles ) { aResult.inout() = theAngles; @@ -3739,7 +3057,6 @@ SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements, CORBA::Boolean theCopy, bool theMakeGroups, ::SMESH_Mesh* theTargetMesh) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -3782,17 +3099,14 @@ SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements, ::SMESH_MeshEditor::PGroupIDs groupIds = getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh); - if ( theCopy && !myIsPreviewMode) + if ( !myIsPreviewMode ) { if ( theTargetMesh ) - { theTargetMesh->GetMeshDS()->Modified(); - } else - { declareMeshModified( /*isReComputeSafe=*/false ); - } } + return theMakeGroups ? getGroups(groupIds.get()) : 0; SMESH_CATCH( SMESH::throwCorbaException ); @@ -3804,11 +3118,10 @@ SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements, //purpose : //======================================================================= -void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements, +void SMESH_MeshEditor_i::Mirror(const SMESH::smIdType_array & theIDsOfElements, const SMESH::AxisStruct & theAxis, SMESH::SMESH_MeshEditor::MirrorType theMirrorType, CORBA::Boolean theCopy) - throw (SALOME::SALOME_Exception) { if ( !myIsPreviewMode ) { TPythonDump() << this << ".Mirror( " @@ -3835,7 +3148,6 @@ void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObj const SMESH::AxisStruct & theAxis, SMESH::SMESH_MeshEditor::MirrorType theMirrorType, CORBA::Boolean theCopy) - throw (SALOME::SALOME_Exception) { if ( !myIsPreviewMode ) { TPythonDump() << this << ".MirrorObject( " @@ -3848,7 +3160,6 @@ void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObj bool emptyIfIsMesh = myIsPreviewMode ? false : true; - prepareIdSource( theObject ); if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh)) mirror(elements, theAxis, theMirrorType, theCopy, false); } @@ -3859,10 +3170,9 @@ void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObj //======================================================================= SMESH::ListOfGroups* -SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements, +SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::smIdType_array& theIDsOfElements, const SMESH::AxisStruct& theMirror, SMESH::SMESH_MeshEditor::MirrorType theMirrorType) - throw (SALOME::SALOME_Exception) { TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() @@ -3892,13 +3202,11 @@ SMESH::ListOfGroups* SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject, const SMESH::AxisStruct& theMirror, SMESH::SMESH_MeshEditor::MirrorType theMirrorType) - throw (SALOME::SALOME_Exception) { TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() SMESH::ListOfGroups * aGroups = 0; TIDSortedElemSet elements; - prepareIdSource( theObject ); if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) aGroups = mirror(elements, theMirror, theMirrorType, true, true); @@ -3919,12 +3227,11 @@ SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr t //======================================================================= SMESH::SMESH_Mesh_ptr -SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements, +SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::smIdType_array& theIDsOfElements, const SMESH::AxisStruct& theMirror, SMESH::SMESH_MeshEditor::MirrorType theMirrorType, CORBA::Boolean theCopyGroups, const char* theMeshName) - throw (SALOME::SALOME_Exception) { SMESH_Mesh_i* mesh_i; SMESH::SMESH_Mesh_var mesh; @@ -3972,7 +3279,6 @@ SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr the SMESH::SMESH_MeshEditor::MirrorType theMirrorType, CORBA::Boolean theCopyGroups, const char* theMeshName) - throw (SALOME::SALOME_Exception) { SMESH_Mesh_i* mesh_i; SMESH::SMESH_Mesh_var mesh; @@ -3984,7 +3290,6 @@ SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr the mesh = makeMesh( theMeshName ); mesh_i = SMESH::DownCast( mesh ); TIDSortedElemSet elements; - prepareIdSource( theObject ); if ( mesh_i && idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) { @@ -4020,7 +3325,6 @@ SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements, CORBA::Boolean theCopy, bool theMakeGroups, ::SMESH_Mesh* theTargetMesh) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -4052,16 +3356,12 @@ SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements, ::SMESH_MeshEditor::PGroupIDs groupIds = getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh); - if ( theCopy && !myIsPreviewMode ) + if ( !myIsPreviewMode ) { if ( theTargetMesh ) - { theTargetMesh->GetMeshDS()->Modified(); - } else - { declareMeshModified( /*isReComputeSafe=*/false ); - } } return theMakeGroups ? getGroups(groupIds.get()) : 0; @@ -4075,10 +3375,9 @@ SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements, //purpose : //======================================================================= -void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements, - const SMESH::DirStruct & theVector, - CORBA::Boolean theCopy) - throw (SALOME::SALOME_Exception) +void SMESH_MeshEditor_i::Translate(const SMESH::smIdType_array & theIDsOfElements, + const SMESH::DirStruct & theVector, + CORBA::Boolean theCopy) { if (!myIsPreviewMode) { TPythonDump() << this << ".Translate( " @@ -4101,7 +3400,6 @@ void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements, void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject, const SMESH::DirStruct & theVector, CORBA::Boolean theCopy) - throw (SALOME::SALOME_Exception) { if (!myIsPreviewMode) { TPythonDump() << this << ".TranslateObject( " @@ -4112,8 +3410,7 @@ void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject, TIDSortedElemSet elements; bool emptyIfIsMesh = myIsPreviewMode ? false : true; - - prepareIdSource( theObject ); + if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh)) translate(elements, theVector, theCopy, false); } @@ -4124,9 +3421,8 @@ void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject, //======================================================================= SMESH::ListOfGroups* -SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements, - const SMESH::DirStruct& theVector) - throw (SALOME::SALOME_Exception) +SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::smIdType_array& theIDsOfElements, + const SMESH::DirStruct& theVector) { TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() @@ -4153,13 +3449,11 @@ SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElement SMESH::ListOfGroups* SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject, const SMESH::DirStruct& theVector) - throw (SALOME::SALOME_Exception) { TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() SMESH::ListOfGroups * aGroups = 0; TIDSortedElemSet elements; - prepareIdSource( theObject ); if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) aGroups = translate(elements, theVector, true, true); @@ -4178,11 +3472,10 @@ SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObjec //======================================================================= SMESH::SMESH_Mesh_ptr -SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements, - const SMESH::DirStruct& theVector, - CORBA::Boolean theCopyGroups, - const char* theMeshName) - throw (SALOME::SALOME_Exception) +SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::smIdType_array& theIDsOfElements, + const SMESH::DirStruct& theVector, + CORBA::Boolean theCopyGroups, + const char* theMeshName) { SMESH_Mesh_i* mesh_i; SMESH::SMESH_Mesh_var mesh; @@ -4229,7 +3522,6 @@ SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject, const SMESH::DirStruct& theVector, CORBA::Boolean theCopyGroups, const char* theMeshName) - throw (SALOME::SALOME_Exception) { SMESH_TRY; SMESH_Mesh_i* mesh_i; @@ -4242,9 +3534,8 @@ SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject, mesh_i = SMESH::DownCast( mesh ); TIDSortedElemSet elements; - prepareIdSource( theObject ); if ( mesh_i && - idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) + idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) { translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl()); mesh_i->CreateGroupServants(); @@ -4280,7 +3571,6 @@ SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements, CORBA::Boolean theCopy, bool theMakeGroups, ::SMESH_Mesh* theTargetMesh) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -4312,7 +3602,7 @@ SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements, ::SMESH_MeshEditor::PGroupIDs groupIds = getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh); - if ( theCopy && !myIsPreviewMode) + if ( !myIsPreviewMode) { if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified(); else declareMeshModified( /*isReComputeSafe=*/false ); @@ -4329,11 +3619,10 @@ SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements, //purpose : //======================================================================= -void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements, - const SMESH::AxisStruct & theAxis, - CORBA::Double theAngle, - CORBA::Boolean theCopy) - throw (SALOME::SALOME_Exception) +void SMESH_MeshEditor_i::Rotate(const SMESH::smIdType_array & theIDsOfElements, + const SMESH::AxisStruct & theAxis, + CORBA::Double theAngle, + CORBA::Boolean theCopy) { if (!myIsPreviewMode) { TPythonDump() << this << ".Rotate( " @@ -4359,7 +3648,6 @@ void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject, const SMESH::AxisStruct & theAxis, CORBA::Double theAngle, CORBA::Boolean theCopy) - throw (SALOME::SALOME_Exception) { if ( !myIsPreviewMode ) { TPythonDump() << this << ".RotateObject( " @@ -4370,7 +3658,6 @@ void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject, } TIDSortedElemSet elements; bool emptyIfIsMesh = myIsPreviewMode ? false : true; - prepareIdSource( theObject ); if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh)) rotate(elements,theAxis,theAngle,theCopy,false); } @@ -4381,10 +3668,9 @@ void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject, //======================================================================= SMESH::ListOfGroups* -SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements, - const SMESH::AxisStruct& theAxis, - CORBA::Double theAngle) - throw (SALOME::SALOME_Exception) +SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::smIdType_array& theIDsOfElements, + const SMESH::AxisStruct& theAxis, + CORBA::Double theAngle) { TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() @@ -4414,13 +3700,11 @@ SMESH::ListOfGroups* SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject, const SMESH::AxisStruct& theAxis, CORBA::Double theAngle) - throw (SALOME::SALOME_Exception) { TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() SMESH::ListOfGroups * aGroups = 0; TIDSortedElemSet elements; - prepareIdSource( theObject ); if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) aGroups = rotate(elements, theAxis, theAngle, true, true); @@ -4440,12 +3724,11 @@ SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject, //======================================================================= SMESH::SMESH_Mesh_ptr -SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements, - const SMESH::AxisStruct& theAxis, - CORBA::Double theAngleInRadians, - CORBA::Boolean theCopyGroups, - const char* theMeshName) - throw (SALOME::SALOME_Exception) +SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::smIdType_array& theIDsOfElements, + const SMESH::AxisStruct& theAxis, + CORBA::Double theAngleInRadians, + CORBA::Boolean theCopyGroups, + const char* theMeshName) { SMESH_TRY; SMESH::SMESH_Mesh_var mesh; @@ -4498,7 +3781,6 @@ SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject, CORBA::Double theAngleInRadians, CORBA::Boolean theCopyGroups, const char* theMeshName) - throw (SALOME::SALOME_Exception) { SMESH_TRY; SMESH::SMESH_Mesh_var mesh; @@ -4512,7 +3794,6 @@ SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject, mesh_i = SMESH::DownCast( mesh ); TIDSortedElemSet elements; - prepareIdSource( theObject ); if (mesh_i && idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) { @@ -4552,7 +3833,6 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject, CORBA::Boolean theCopy, bool theMakeGroups, ::SMESH_Mesh* theTargetMesh) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -4565,7 +3845,6 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject, theCopy = false; TIDSortedElemSet elements; - prepareIdSource( theObject ); bool emptyIfIsMesh = myIsPreviewMode ? false : true; if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh)) return 0; @@ -4575,11 +3854,19 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject, (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1], (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2], }; - double tol = std::numeric_limits::max(); gp_Trsf aTrsf; - aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]), - 0, S[1], 0, thePoint.y * (1-S[1]), - 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol); + + // fight against orthogonalization + // aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]), + // 0, S[1], 0, thePoint.y * (1-S[1]), + // 0, 0, S[2], thePoint.z * (1-S[2]) ); + aTrsf.SetScale( gp::Origin(), 1.0 ); // set form which is used to make group names + gp_XYZ & loc = ( gp_XYZ& ) aTrsf.TranslationPart(); + gp_Mat & M = ( gp_Mat& ) aTrsf.HVectorialPart(); + loc.SetCoord( thePoint.x * (1-S[0]), + thePoint.y * (1-S[1]), + thePoint.z * (1-S[2])); + M.SetDiagonal( S[0], S[1], S[2] ); TIDSortedElemSet copyElements; TIDSortedElemSet* workElements = &elements; @@ -4600,7 +3887,7 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject, ::SMESH_MeshEditor::PGroupIDs groupIds = getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh); - if ( theCopy && !myIsPreviewMode ) + if ( !myIsPreviewMode ) { if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified(); else declareMeshModified( /*isReComputeSafe=*/false ); @@ -4620,7 +3907,6 @@ void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject, const SMESH::PointStruct& thePoint, const SMESH::double_array& theScaleFact, CORBA::Boolean theCopy) - throw (SALOME::SALOME_Exception) { if ( !myIsPreviewMode ) { TPythonDump() << this << ".Scale( " @@ -4642,7 +3928,6 @@ SMESH::ListOfGroups* SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject, const SMESH::PointStruct& thePoint, const SMESH::double_array& theScaleFact) - throw (SALOME::SALOME_Exception) { TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() @@ -4669,7 +3954,6 @@ SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject, const SMESH::double_array& theScaleFact, CORBA::Boolean theCopyGroups, const char* theMeshName) - throw (SALOME::SALOME_Exception) { SMESH_Mesh_i* mesh_i; SMESH::SMESH_Mesh_var mesh; @@ -4677,7 +3961,7 @@ SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject, // and then "GetGroups" using SMESH_Mesh::GetGroups() TPythonDump pydump; // to prevent dump at mesh creation - mesh = makeMesh( theMeshName ); + mesh = makeMesh( theMeshName ); mesh_i = SMESH::DownCast( mesh ); if ( mesh_i ) @@ -4694,34 +3978,127 @@ SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject, << theMeshName << "' )"; } - // dump "GetGroups" - if (!myIsPreviewMode && mesh_i) - mesh_i->GetGroups(); + // dump "GetGroups" + if (!myIsPreviewMode && mesh_i) + mesh_i->GetGroups(); + + return mesh._retn(); +} + +//================================================================================ +/*! + * \brief Make an offset mesh from a source 2D mesh + * \param [inout] theObject - source mesh. New elements are added to this mesh + * if \a theMeshName is empty. + * \param [in] theValue - offset value + * \param [in] theCopyGroups - to generate groups + * \param [in] theMeshName - optional name of a new mesh + * \param [out] theGroups - new groups + * \return SMESH::SMESH_Mesh_ptr - the modified mesh + */ +//================================================================================ + +SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::Offset( SMESH::SMESH_IDSource_ptr theObject, + CORBA::Double theValue, + CORBA::Boolean theCopyGroups, + CORBA::Boolean theCopyElements, + const char* theMeshName, + SMESH::ListOfGroups_out theGroups) +{ + SMESH_TRY; + initData(); + + SMESHDS_Mesh* aMeshDS = getMeshDS(); + + SMESH::SMESH_Mesh_var mesh_var; + ::SMESH_MeshEditor::PGroupIDs groupIds; + + TPythonDump pyDump; + + TIDSortedElemSet elements, copyElements; + if ( idSourceToSet( theObject, aMeshDS, elements, SMDSAbs_Face, + /*emptyIfIsMesh=*/ !myIsPreviewMode )) + { + // mesh to modify + SMESH_Mesh* tgtMesh = 0; + if ( myIsPreviewMode ) + { + TPreviewMesh * tmpMesh = getPreviewMesh(); + tgtMesh = tmpMesh; + tmpMesh->Copy( elements, copyElements ); + elements.swap( copyElements ); + theCopyGroups = false; + theCopyElements = false; + } + else + { + mesh_var = + *theMeshName ? makeMesh( theMeshName ) : SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() ); + SMESH_Mesh_i* mesh_i = SMESH::DownCast( mesh_var ); + tgtMesh = & mesh_i->GetImpl(); + } + groupIds = getEditor().Offset( elements, theValue, tgtMesh, + theCopyGroups, theCopyElements, !myIsPreviewMode ); + + tgtMesh->GetMeshDS()->Modified(); + } + + if ( myIsPreviewMode ) + { + //getPreviewMesh()->Remove( SMESHUtils::elemSetIterator( copyElements )); + } + else + { + if ( *theMeshName && mesh_var->NbFaces() == 0 ) + { + // new mesh empty, remove it + SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->getStudyServant(); + SALOMEDS::StudyBuilder_var builder = study->NewBuilder(); + SALOMEDS::SObject_wrap meshSO = SMESH_Gen_i::GetSMESHGen()->ObjectToSObject( mesh_var ); + builder->RemoveObjectWithChildren( meshSO ); + THROW_SALOME_CORBA_EXCEPTION("Offset failed", SALOME::INTERNAL_ERROR); + } + if ( !groupIds ) // nothing changed in the current mesh + THROW_SALOME_CORBA_EXCEPTION("Offset failed", SALOME::INTERNAL_ERROR); + + theGroups = theCopyGroups ? getGroups( groupIds.get() ) : new SMESH::ListOfGroups; - return mesh._retn(); -} + // result of Offset() is a tuple (mesh, groups) + if ( mesh_var->_is_nil() ) pyDump << myMesh_i->_this() << ", "; + else pyDump << mesh_var << ", "; + pyDump << theGroups << " = " << this << ".Offset( " + << theObject << ", " + << theValue << ", " + << theCopyGroups << ", " + << theCopyElements << ", " + << "'" << theMeshName<< "')"; + } + + return mesh_var._retn(); + SMESH_CATCH( SMESH::throwCorbaException ); + return SMESH::SMESH_Mesh::_nil(); +} //======================================================================= -//function : FindCoincidentNodes +//function : findCoincidentNodes //purpose : //======================================================================= -void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance, - SMESH::array_of_long_array_out GroupsOfNodes) - throw (SALOME::SALOME_Exception) +void SMESH_MeshEditor_i:: +findCoincidentNodes (TIDSortedNodeSet & Nodes, + CORBA::Double Tolerance, + SMESH::array_of_long_array_out GroupsOfNodes, + CORBA::Boolean SeparateCornersAndMedium) { - SMESH_TRY; - initData(); - ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes; - TIDSortedNodeSet nodes; // no input nodes - getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes ); + getEditor().FindCoincidentNodes( Nodes, Tolerance, aListOfListOfNodes, SeparateCornersAndMedium ); GroupsOfNodes = new SMESH::array_of_long_array; GroupsOfNodes->length( aListOfListOfNodes.size() ); ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin(); - for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) { + for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) + { list< const SMDS_MeshNode* >& aListOfNodes = *llIt; list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();; SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ]; @@ -4729,8 +4106,27 @@ void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tol for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ ) aGroup[ j ] = (*lIt)->GetID(); } +} + +//======================================================================= +//function : FindCoincidentNodes +//purpose : +//======================================================================= + +void SMESH_MeshEditor_i:: +FindCoincidentNodes (CORBA::Double Tolerance, + SMESH::array_of_long_array_out GroupsOfNodes, + CORBA::Boolean SeparateCornersAndMedium) +{ + SMESH_TRY; + initData(); + + TIDSortedNodeSet nodes; // no input nodes + findCoincidentNodes( nodes, Tolerance, GroupsOfNodes, SeparateCornersAndMedium ); + TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( " - << Tolerance << " )"; + << Tolerance << ", " + << SeparateCornersAndMedium << " )"; SMESH_CATCH( SMESH::throwCorbaException ); } @@ -4740,10 +4136,11 @@ void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tol //purpose : //======================================================================= -void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject, - CORBA::Double Tolerance, - SMESH::array_of_long_array_out GroupsOfNodes) - throw (SALOME::SALOME_Exception) +void SMESH_MeshEditor_i:: +FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject, + CORBA::Double Tolerance, + SMESH::array_of_long_array_out GroupsOfNodes, + CORBA::Boolean SeparateCornersAndMedium) { SMESH_TRY; initData(); @@ -4752,78 +4149,53 @@ void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr prepareIdSource( theObject ); idSourceToNodeSet( theObject, getMeshDS(), nodes ); - ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes; - if(!nodes.empty()) - getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes ); + findCoincidentNodes( nodes, Tolerance, GroupsOfNodes, SeparateCornersAndMedium ); - GroupsOfNodes = new SMESH::array_of_long_array; - GroupsOfNodes->length( aListOfListOfNodes.size() ); - ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin(); - for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) - { - list< const SMDS_MeshNode* >& aListOfNodes = *llIt; - list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();; - SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ]; - aGroup.length( aListOfNodes.size() ); - for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ ) - aGroup[ j ] = (*lIt)->GetID(); - } TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( " - <length( aListOfListOfNodes.size() ); - ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin(); - for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) + for ( CORBA::ULong i = 0; i < theExceptSubMeshOrGroups.length(); ++i ) { - list< const SMDS_MeshNode* >& aListOfNodes = *llIt; - list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();; - SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ]; - aGroup.length( aListOfNodes.size() ); - for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ ) - aGroup[ j ] = (*lIt)->GetID(); + if ( SMDS_ElemIteratorPtr nodeIt = myMesh_i->GetElements( theExceptSubMeshOrGroups[i], + SMESH::NODE )) + while ( nodeIt->more() ) + nodes.erase( cast2Node( nodeIt->next() )); } + findCoincidentNodes( nodes, theTolerance, theGroupsOfNodes, theSeparateCornersAndMedium ); + TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( " - << theObject<<", " + << theObjects <<", " << theTolerance << ", " - << theExceptSubMeshOrGroups << " )"; + << theExceptSubMeshOrGroups << ", " + << theSeparateCornersAndMedium << " )"; SMESH_CATCH( SMESH::throwCorbaException ); } @@ -4833,8 +4205,9 @@ FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject, //purpose : //======================================================================= -void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes) - throw (SALOME::SALOME_Exception) +void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes, + const SMESH::ListOfIDSources& NodesToKeep, + CORBA::Boolean AvoidMakingHoles) { SMESH_TRY; initData(); @@ -4843,18 +4216,32 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN TPythonDump aTPythonDump; aTPythonDump << this << ".MergeNodes(["; + + TIDSortedNodeSet setOfNodesToKeep; + for ( CORBA::ULong i = 0; i < NodesToKeep.length(); ++i ) + { + prepareIdSource( NodesToKeep[i] ); + if ( SMDS_ElemIteratorPtr nodeIt = myMesh_i->GetElements( NodesToKeep[i], SMESH::NODE )) + while ( nodeIt->more() ) + setOfNodesToKeep.insert( setOfNodesToKeep.end(), cast2Node( nodeIt->next() )); + } + ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes; - for (int i = 0; i < GroupsOfNodes.length(); i++) + for ( CORBA::ULong i = 0; i < GroupsOfNodes.length(); i++ ) { const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ]; aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() ); list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back(); - for ( int j = 0; j < aNodeGroup.length(); j++ ) + for ( CORBA::ULong j = 0; j < aNodeGroup.length(); j++ ) { CORBA::Long index = aNodeGroup[ j ]; - const SMDS_MeshNode * node = aMesh->FindNode(index); - if ( node ) - aListOfNodes.push_back( node ); + if ( const SMDS_MeshNode * node = aMesh->FindNode( index )) + { + if ( setOfNodesToKeep.count( node )) + aListOfNodes.push_front( node ); + else + aListOfNodes.push_back( node ); + } } if ( aListOfNodes.size() < 2 ) aListOfListOfNodes.pop_back(); @@ -4862,9 +4249,10 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN if ( i > 0 ) aTPythonDump << ", "; aTPythonDump << aNodeGroup; } - getEditor().MergeNodes( aListOfListOfNodes ); - aTPythonDump << "])"; + getEditor().MergeNodes( aListOfListOfNodes, AvoidMakingHoles ); + + aTPythonDump << "], " << NodesToKeep << ", " << AvoidMakingHoles << ")"; declareMeshModified( /*isReComputeSafe=*/false ); @@ -4876,40 +4264,56 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN //purpose : //======================================================================= -void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject, - SMESH::array_of_long_array_out GroupsOfElementsID) - throw (SALOME::SALOME_Exception) +void SMESH_MeshEditor_i::FindEqualElements(const SMESH::ListOfIDSources& theObjects, + const SMESH::ListOfIDSources& theExceptObjects, + SMESH::array_of_long_array_out theGroupsOfElementsID) { SMESH_TRY; initData(); - SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject); - if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) ) + theGroupsOfElementsID = new SMESH::array_of_long_array; + + TIDSortedElemSet elems; + bool hasOkObject = false; + bool emptyIfIsMesh= ( theObjects.length() == 1 && theExceptObjects.length() == 0 ); + + for ( CORBA::ULong i = 0; i < theObjects.length(); ++i ) + { + SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow( theObjects[i] ); + if ( !( !group->_is_nil() && group->GetType() == SMESH::NODE )) + if ( idSourceToSet( theObjects[i], getMeshDS(), elems, SMDSAbs_All, emptyIfIsMesh )) + hasOkObject = true; + } + + if ( hasOkObject ) { - TIDSortedElemSet elems; - prepareIdSource( theObject ); - idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true); + for ( CORBA::ULong i = 0; i < theExceptObjects.length(); ++i ) + { + if ( SMDS_ElemIteratorPtr elemIt = myMesh_i->GetElements( theExceptObjects[i], SMESH::ALL )) + while ( elemIt->more() ) + elems.erase( elemIt->next() ); + } ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID; getEditor().FindEqualElements( elems, aListOfListOfElementsID ); - GroupsOfElementsID = new SMESH::array_of_long_array; - GroupsOfElementsID->length( aListOfListOfElementsID.size() ); + theGroupsOfElementsID->length( aListOfListOfElementsID.size() ); ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin(); for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) { - SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ]; - list& listOfIDs = *arraysIt; + SMESH::long_array& aGroup = (*theGroupsOfElementsID)[ j ]; + list& listOfIDs = *arraysIt; aGroup.length( listOfIDs.size() ); - list::iterator idIt = listOfIDs.begin(); - for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) + list::iterator idIt = listOfIDs.begin(); + for (smIdType k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) aGroup[ k ] = *idIt; } TPythonDump() << "equal_elements = " << this << ".FindEqualElements( " - < idsToKeep; + for ( CORBA::ULong i = 0; i < theElementsToKeep.length(); i++ ) + { + if ( CORBA::is_nil( theElementsToKeep[i] )) + continue; + SMESH::array_of_ElementType_var elemTypes = theElementsToKeep[i]->GetTypes(); + if ( elemTypes->length() == 1 && elemTypes[0] == SMESH::NODE ) + continue; + SMESH::smIdType_array_var elementsId = theElementsToKeep[i]->GetIDs(); + for ( SMESH::smIdType j = 0; j < elementsId->length(); ++j ) + idsToKeep.Add( elementsId[ j ]); + } + ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID; - for (int i = 0; i < GroupsOfElementsID.length(); i++) { - const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ]; - aListOfListOfElementsID.push_back( list< int >() ); - list< int >& aListOfElemsID = aListOfListOfElementsID.back(); - for ( int j = 0; j < anElemsIDGroup.length(); j++ ) { - CORBA::Long id = anElemsIDGroup[ j ]; - aListOfElemsID.push_back( id ); + for ( CORBA::ULong i = 0; i < theGroupsOfElementsID.length(); i++ ) + { + const SMESH::long_array& anElemsIDGroup = theGroupsOfElementsID[ i ]; + aListOfListOfElementsID.push_back( list< smIdType >() ); + list< smIdType >& aListOfElemsID = aListOfListOfElementsID.back(); + for ( SMESH::smIdType j = 0; j < anElemsIDGroup.length(); j++ ) + { + SMESH::smIdType id = anElemsIDGroup[ j ]; + if ( idsToKeep.Contains( id )) aListOfElemsID.push_front( id ); + else aListOfElemsID.push_back( id ); } if ( aListOfElemsID.size() < 2 ) aListOfListOfElementsID.pop_back(); @@ -4949,7 +4369,7 @@ void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsO declareMeshModified( /*isReComputeSafe=*/true ); - aTPythonDump << "] )"; + aTPythonDump << "], " << theElementsToKeep << " )"; SMESH_CATCH( SMESH::throwCorbaException ); } @@ -4960,7 +4380,6 @@ void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsO //======================================================================= void SMESH_MeshEditor_i::MergeEqualElements() - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -4980,11 +4399,10 @@ void SMESH_MeshEditor_i::MergeEqualElements() */ //============================================================================= -CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID, - CORBA::Double x, - CORBA::Double y, - CORBA::Double z) - throw (SALOME::SALOME_Exception) +CORBA::Boolean SMESH_MeshEditor_i::MoveNode(SMESH::smIdType NodeID, + CORBA::Double x, + CORBA::Double y, + CORBA::Double z) { SMESH_TRY; initData(/*deleteSearchers=*/false); @@ -5038,10 +4456,9 @@ CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID, */ //================================================================================ -CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x, +SMESH::smIdType SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x, CORBA::Double y, CORBA::Double z) - throw (SALOME::SALOME_Exception) { SMESH_TRY; theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other @@ -5064,11 +4481,10 @@ CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x, */ //================================================================================ -CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x, - CORBA::Double y, - CORBA::Double z, - CORBA::Long theNodeID) - throw (SALOME::SALOME_Exception) +SMESH::smIdType SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x, + CORBA::Double y, + CORBA::Double z, + SMESH::smIdType theNodeID) { SMESH_TRY; // We keep theNodeSearcher until any mesh modification: @@ -5079,7 +4495,7 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x, theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other - int nodeID = theNodeID; + smIdType nodeID = theNodeID; const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID ); if ( !node ) // preview moving node { @@ -5142,14 +4558,13 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x, */ //======================================================================= -SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x, +SMESH::smIdType_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x, CORBA::Double y, CORBA::Double z, SMESH::ElementType type) - throw (SALOME::SALOME_Exception) { SMESH_TRY; - SMESH::long_array_var res = new SMESH::long_array; + SMESH::smIdType_array_var res = new SMESH::smIdType_array; vector< const SMDS_MeshElement* > foundElems; theSearchersDeleter.Set( myMesh ); @@ -5160,16 +4575,9 @@ SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x, SMDSAbs_ElementType( type ), foundElems); res->length( foundElems.size() ); - for ( int i = 0; i < foundElems.size(); ++i ) + for ( size_t i = 0; i < foundElems.size(); ++i ) res[i] = foundElems[i]->GetID(); - if ( !myIsPreviewMode ) // call from tui - TPythonDump() << "res = " << this << ".FindElementsByPoint( " - << x << ", " - << y << ", " - << z << ", " - << type << " )"; - return res._retn(); SMESH_CATCH( SMESH::throwCorbaException ); @@ -5183,88 +4591,440 @@ SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x, // 'ALL' type means elements of any type excluding nodes //======================================================================= -SMESH::long_array* +SMESH::smIdType_array* SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs, CORBA::Double x, CORBA::Double y, CORBA::Double z, SMESH::ElementType type) - throw (SALOME::SALOME_Exception) { SMESH_TRY; - SMESH::long_array_var res = new SMESH::long_array; - - SMESH::array_of_ElementType_var types = elementIDs->GetTypes(); - if ( types->length() == 1 && // a part contains only nodes or 0D elements - ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) && - type != types[0] ) // but search of elements of dim > 0 - return res._retn(); + SMESH::smIdType_array_var res = new SMESH::smIdType_array; + + prepareIdSource( elementIDs ); + if ( type != SMESH::NODE ) + { + SMESH::array_of_ElementType_var types = elementIDs->GetTypes(); + if ( types->length() == 1 && // a part contains only nodes or 0D elements + ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) && + type != types[0] ) // but search of elements of dim > 0 + return res._retn(); + } + + SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh(); + SMESH_Mesh_i* mesh_i = SMESH::DownCast( mesh ); + if ( mesh_i != myMesh_i ) + { + SMESH::SMESH_MeshEditor_var editor= + myIsPreviewMode ? mesh_i->GetMeshEditPreviewer() : mesh_i->GetMeshEditor(); + return editor->FindAmongElementsByPoint( elementIDs, x,y,z, type ); + } if ( SMESH::DownCast( elementIDs )) // elementIDs is the whole mesh return FindElementsByPoint( x,y,z, type ); - TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes + TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes + + theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type )); + if ( !theElementSearcher ) + { + // create a searcher from elementIDs + SMDS_ElemIteratorPtr elemIt; + if ( ! SMESH::DownCast( elementIDs )) + { + //prepareIdSource( elementIDs ); + elemIt = myMesh_i->GetElements( elementIDs, type ); + if ( !elemIt ) + return res._retn(); + } + theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemIt ); + } + + vector< const SMDS_MeshElement* > foundElems; + + theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ), + SMDSAbs_ElementType( type ), + foundElems); + res->length( foundElems.size() ); + for ( size_t i = 0; i < foundElems.size(); ++i ) + res[i] = foundElems[i]->GetID(); + + return res._retn(); + + SMESH_CATCH( SMESH::throwCorbaException ); + return 0; +} + +//======================================================================= +//function : ProjectPoint +//purpose : Project a point to a mesh object. +// Return ID of an element of given type where the given point is projected +// and coordinates of the projection point. +// In the case if nothing found, return -1 and [] +//======================================================================= + +SMESH::smIdType SMESH_MeshEditor_i::ProjectPoint(CORBA::Double x, + CORBA::Double y, + CORBA::Double z, + SMESH::ElementType type, + SMESH::SMESH_IDSource_ptr meshObject, + SMESH::double_array_out projecton) +{ + if ( CORBA::is_nil( meshObject )) + THROW_SALOME_CORBA_EXCEPTION("NULL meshObject", SALOME::BAD_PARAM); + + SMESH_TRY; + + SMESH::SMESH_Mesh_var mesh = meshObject->GetMesh(); + SMESH_Mesh_i* mesh_i = SMESH::DownCast( mesh ); + if ( mesh_i != myMesh_i ) + { + SMESH::SMESH_MeshEditor_var editor= + myIsPreviewMode ? mesh_i->GetMeshEditPreviewer() : mesh_i->GetMeshEditor(); + return editor->ProjectPoint( x,y,z, type, meshObject, projecton ); + } + + + theSearchersDeleter.Set( myMesh, getPartIOR( meshObject, type )); + if ( !theElementSearcher ) + { + // create a searcher from meshObject + + SMDS_ElemIteratorPtr elemIt; + if ( ! SMESH::DownCast( meshObject )) + { + prepareIdSource( meshObject ); + elemIt = myMesh_i->GetElements( meshObject, type ); + if ( !elemIt ) + return -1; + } + theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemIt ); + } + + const SMDS_MeshElement* elem = 0; + gp_XYZ pProj = theElementSearcher->Project( gp_Pnt( x,y,z ), + SMDSAbs_ElementType( type ), + &elem ); + + projecton = new SMESH::double_array(); + if ( elem && !elem->IsNull() ) + { + projecton->length( 3 ); + projecton[0] = pProj.X(); + projecton[1] = pProj.Y(); + projecton[2] = pProj.Z(); + return elem->GetID(); + } + + SMESH_CATCH( SMESH::throwCorbaException ); + return -1; +} + +//======================================================================= +//function : GetPointState +//purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration. +// TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails. +//======================================================================= + +CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x, + CORBA::Double y, + CORBA::Double z) +{ + SMESH_TRY; + theSearchersDeleter.Set( myMesh ); + if ( !theElementSearcher ) { + theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() ); + } + return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z ))); + + SMESH_CATCH( SMESH::throwCorbaException ); + return 0; +} + +//======================================================================= +//function : IsManifold +//purpose : Check if a 2D mesh is manifold +//======================================================================= + +CORBA::Boolean SMESH_MeshEditor_i::IsManifold() +{ + bool isManifold = true; + + SMESH_TRY; + SMESH_MeshAlgos::TFreeBorderVec foundFreeBordes; + SMESH_MeshAlgos::FindFreeBorders( *getMeshDS(), + foundFreeBordes, + /*closedOnly=*/true, + &isManifold ); + SMESH_CATCH( SMESH::throwCorbaException ); + + return isManifold; +} + +//======================================================================= +//function : IsCoherentOrientation2D +//purpose : Check if orientation of 2D elements is coherent +//======================================================================= + +CORBA::Boolean SMESH_MeshEditor_i::IsCoherentOrientation2D() +{ + bool isGoodOri = true; + + SMESH_TRY; + SMESH_MeshAlgos::TFreeBorderVec foundFreeBordes; + SMESH_MeshAlgos::FindFreeBorders( *getMeshDS(), + foundFreeBordes, + /*closedOnly=*/true, + /*isManifold=*/0, + &isGoodOri); + SMESH_CATCH( SMESH::throwCorbaException ); + + return isGoodOri; +} + +//======================================================================= +//function : Get1DBranches +//purpose : Partition given 1D elements into groups of contiguous edges. +// A node where number of meeting edges != 2 is a group end. +// An optional startNode is used to orient groups it belongs to. +//return : a list of edge groups and a list of corresponding node groups. +// If a group is closed, the first and last nodes of the group are same. +//======================================================================= + +SMESH::array_of_long_array* +SMESH_MeshEditor_i::Get1DBranches( SMESH::SMESH_IDSource_ptr theEdges, + SMESH::smIdType theStartNode, + SMESH::array_of_long_array_out theNodeGroups ) +{ + if ( CORBA::is_nil( theEdges )) + THROW_SALOME_CORBA_EXCEPTION("Get1DBranches(): NULL group given", SALOME::BAD_PARAM); + + SMESH::array_of_long_array_var edgeGroupArray = new SMESH::array_of_long_array; + theNodeGroups = new SMESH::array_of_long_array; + + SMESH_TRY; + + prepareIdSource( theEdges ); + + SMESH_MeshAlgos::TElemGroupVector edgeBranches; + SMESH_MeshAlgos::TNodeGroupVector nodeBranches; + SMESH_MeshAlgos::Get1DBranches( SMESH_Mesh_i::GetElements( theEdges, SMESH::EDGE ), + edgeBranches, + nodeBranches, + getMeshDS()->FindNode( theStartNode )); + + edgeGroupArray->length( edgeBranches.size() ); + for ( size_t iG = 0; iG < edgeBranches.size(); ++iG ) + { + edgeGroupArray[ iG ].length( edgeBranches[ iG ].size() ); + for ( size_t i = 0; i < edgeBranches[ iG ].size(); ++i ) + edgeGroupArray[ iG ][ i ] = edgeBranches[ iG ][ i ]->GetID(); + } + + theNodeGroups->length( nodeBranches.size() ); + for ( size_t iG = 0; iG < nodeBranches.size(); ++iG ) + { + theNodeGroups[ iG ].length( nodeBranches[ iG ].size() ); + for ( size_t i = 0; i < nodeBranches[ iG ].size(); ++i ) + theNodeGroups[ iG ][ i ] = nodeBranches[ iG ][ i ]->GetID(); + } + + SMESH_CATCH( SMESH::throwCorbaException ); + + return edgeGroupArray._retn(); +} + +//======================================================================= +//function : FindSharpEdges +//purpose : Return sharp edges of faces and non-manifold ones. Optionally add existing edges. +//======================================================================= + +SMESH::ListOfEdges* SMESH_MeshEditor_i::FindSharpEdges(CORBA::Double theAngle, + CORBA::Boolean theAddExisting) +{ + SMESH::ListOfEdges_var resultEdges = new SMESH::ListOfEdges; + SMESH_TRY; + + initData(); + + std::vector< SMESH_MeshAlgos::Edge > edges = + SMESH_MeshAlgos::FindSharpEdges( getMeshDS(), theAngle, theAddExisting ); + + if ( myIsPreviewMode ) // fill a preview mesh with edges + { + TPreviewMesh* mesh = getPreviewMesh( SMDSAbs_Edge ); + SMDS_Mesh* meshDS = mesh->GetMeshDS(); + for ( size_t i = 0; i < edges.size(); ++i ) + { + SMESH_NodeXYZ xyz1( edges[i]._node1), xyz2( edges[i]._node2); + SMDS_MeshNode* n1 = meshDS->AddNode( xyz1.X(), xyz1.Y(), xyz1.Z() ); + SMDS_MeshNode* n2 = meshDS->AddNode( xyz2.X(), xyz2.Y(), xyz2.Z() ); + if ( edges[i]._medium ) + { + xyz1.Set( edges[i]._medium ); + SMDS_MeshNode* nm = meshDS->AddNode( xyz1.X(), xyz1.Y(), xyz1.Z() ); + mesh->GetMeshDS()->AddEdge( n1, n2, nm ); + } + else + { + mesh->GetMeshDS()->AddEdge( n1, n2 ); + } + } + } + else + { + resultEdges->length( edges.size() ); + for ( size_t i = 0; i < edges.size(); ++i ) + { + resultEdges[ i ].node1 = edges[i]._node1->GetID(); + resultEdges[ i ].node2 = edges[i]._node2->GetID(); + resultEdges[ i ].medium = edges[i]._medium ? edges[i]._medium->GetID() : 0; + } + } + SMESH_CATCH( SMESH::throwCorbaException ); + return resultEdges._retn(); +} + +//======================================================================= +//function : FindFreeBorders +//purpose : Returns all or only closed FreeBorder's. +//======================================================================= + +SMESH::ListOfFreeBorders* SMESH_MeshEditor_i::FindFreeBorders(CORBA::Boolean closedOnly) +{ + SMESH::ListOfFreeBorders_var resBorders = new SMESH::ListOfFreeBorders; + SMESH_TRY; + + SMESH_MeshAlgos::TFreeBorderVec foundFreeBordes; + SMESH_MeshAlgos::FindFreeBorders( *getMeshDS(), foundFreeBordes, closedOnly ); + + resBorders->length( foundFreeBordes.size() ); + for ( size_t i = 0; i < foundFreeBordes.size(); ++i ) + { + const SMESH_MeshAlgos::TFreeBorder& bordNodes = foundFreeBordes[i]; + SMESH::FreeBorder& bordOut = resBorders[i]; + bordOut.nodeIDs.length( bordNodes.size() ); + for ( size_t iN = 0; iN < bordNodes.size(); ++iN ) + bordOut.nodeIDs[ iN ] = bordNodes[ iN ]->GetID(); + } + + SMESH_CATCH( SMESH::throwCorbaException ); + + return resBorders._retn(); +} + +//======================================================================= +//function : FillHole +//purpose : Fill with 2D elements a hole defined by a FreeBorder. +//======================================================================= + +SMESH::SMESH_Group_ptr +SMESH_MeshEditor_i::FillHole(const SMESH::FreeBorder& theHole, + const char* theGroupName) +{ + initData(); + + if ( theHole.nodeIDs.length() < 4 ) + THROW_SALOME_CORBA_EXCEPTION("A hole should be bound by at least 3 nodes", SALOME::BAD_PARAM); + if ( theHole.nodeIDs[0] != theHole.nodeIDs[ theHole.nodeIDs.length()-1 ] ) + THROW_SALOME_CORBA_EXCEPTION("Not closed hole boundary. " + "First and last nodes must be same", SALOME::BAD_PARAM); - theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type )); - if ( !theElementSearcher ) + SMESH_MeshAlgos::TFreeBorder bordNodes; + bordNodes.resize( theHole.nodeIDs.length() ); + for ( size_t iN = 0; iN < theHole.nodeIDs.length(); ++iN ) { - // create a searcher from elementIDs - SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh(); - SMESHDS_Mesh* meshDS = SMESH::DownCast( mesh )->GetImpl().GetMeshDS(); - - if ( !idSourceToSet( elementIDs, meshDS, elements, - SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true)) - return res._retn(); + bordNodes[ iN ] = getMeshDS()->FindNode( theHole.nodeIDs[ iN ]); + if ( !bordNodes[ iN ] ) + THROW_SALOME_CORBA_EXCEPTION(SMESH_Comment("Node #") << theHole.nodeIDs[ iN ] + << " does not exist", SALOME::BAD_PARAM); + } - typedef SMDS_SetIterator TIter; - SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() )); + SMESH_TRY; - theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt ); + // prepare a preview mesh + MeshEditor_I::TPreviewMesh* previewMesh = 0; + SMDS_Mesh* meshDS = getMeshDS(); + if ( myIsPreviewMode ) + { + // copy faces sharing nodes of theHole + TIDSortedElemSet holeFaces; + previewMesh = getPreviewMesh( SMDSAbs_Face ); + for ( size_t i = 0; i < bordNodes.size(); ++i ) + { + SMDS_ElemIteratorPtr fIt = bordNodes[i]->GetInverseElementIterator( SMDSAbs_Face ); + while ( fIt->more() ) + { + const SMDS_MeshElement* face = fIt->next(); + if ( holeFaces.insert( face ).second ) + previewMesh->Copy( face ); + } + bordNodes[i] = previewMesh->GetMeshDS()->FindNode( bordNodes[i]->GetID() ); + ASSERT( bordNodes[i] ); + } + meshDS = previewMesh->GetMeshDS(); } - vector< const SMDS_MeshElement* > foundElems; - - theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ), - SMDSAbs_ElementType( type ), - foundElems); - res->length( foundElems.size() ); - for ( int i = 0; i < foundElems.size(); ++i ) - res[i] = foundElems[i]->GetID(); + // fill the hole + std::vector newFaces; + SMESH_MeshAlgos::FillHole( bordNodes, *meshDS, newFaces ); - if ( !myIsPreviewMode ) // call from tui - TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( " - << elementIDs << ", " - << x << ", " - << y << ", " - << z << ", " - << type << " )"; + if ( myIsPreviewMode ) + { + // show new faces + previewMesh->Clear(); + for ( size_t i = 0; i < newFaces.size(); ++i ) + previewMesh->Copy( newFaces[i] ); + } + else + { + // return new faces via a group + SMESH::SMESH_Group_var group; + if ( theGroupName && theGroupName[0] && !newFaces.empty() ) + { + SMESH::ListOfGroups_var groups = myMesh_i->GetGroups(); + for ( CORBA::ULong i = 0; i < groups->length(); ++i ) + { + SMESH::SMESH_GroupBase_var g = groups[ i ]; + if ( g->GetType() != SMESH::FACE ) continue; + SMESH::SMESH_Group_var standalone = SMESH::SMESH_Group::_narrow( g ); + if ( standalone->_is_nil() ) continue; + CORBA::String_var name = g->GetName(); + if ( strcmp( theGroupName, name.in() ) == 0 ) + { + group = standalone; + break; + } + } + if ( group->_is_nil() ) + group = myMesh_i->CreateGroup( SMESH::FACE, theGroupName ); - return res._retn(); + if ( !group->_is_nil() ) + { + SMESH_GroupBase_i * grpI = SMESH::DownCast< SMESH_GroupBase_i* >( group ); + SMESHDS_Group* grpDS = static_cast< SMESHDS_Group* >( grpI->GetGroupDS() ); + for ( size_t i = 0; i < newFaces.size(); ++i ) + grpDS->Add( newFaces[ i ]); + } + } - SMESH_CATCH( SMESH::throwCorbaException ); - return 0; -} + // fill LastCreated + getEditor().ClearLastCreated(); + SMESH_SequenceOfElemPtr& aSeq = + const_cast( getEditor().GetLastCreatedElems() ); + aSeq.swap( newFaces ); -//======================================================================= -//function : GetPointState -//purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration. -// TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails. -//======================================================================= + TPythonDump pyDump; + if ( group->_is_nil() ) pyDump << "_group = "; + else pyDump << group << " = "; + pyDump << this << ".FillHole( SMESH.FreeBorder(" << theHole.nodeIDs << " ))"; -CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x, - CORBA::Double y, - CORBA::Double z) - throw (SALOME::SALOME_Exception) -{ - SMESH_TRY; - theSearchersDeleter.Set( myMesh ); - if ( !theElementSearcher ) { - theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() ); + return group._retn(); } - return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z ))); SMESH_CATCH( SMESH::throwCorbaException ); - return 0; + + return SMESH::SMESH_Group::_nil(); } //======================================================================= @@ -5287,25 +5047,243 @@ static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Se RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS ); RETCASE( SEW_BAD_SIDE1_NODES ); RETCASE( SEW_BAD_SIDE2_NODES ); + RETCASE( SEW_INTERNAL_ERROR ); } return SMESH::SMESH_MeshEditor::SEW_OK; } +//======================================================================= +/*! + * Returns groups of FreeBorder's coincident within the given tolerance. + * If the tolerance <= 0.0 then one tenth of an average size of elements adjacent + * to free borders being compared is used. + */ +//======================================================================= + +SMESH::CoincidentFreeBorders* +SMESH_MeshEditor_i::FindCoincidentFreeBorders(CORBA::Double tolerance) +{ + SMESH::CoincidentFreeBorders_var aCFB = new SMESH::CoincidentFreeBorders; + + SMESH_TRY; + + SMESH_MeshAlgos::CoincidentFreeBorders cfb; + SMESH_MeshAlgos::FindCoincidentFreeBorders( *getMeshDS(), tolerance, cfb ); + + // copy free borders + aCFB->borders.length( cfb._borders.size() ); + for ( size_t i = 0; i < cfb._borders.size(); ++i ) + { + SMESH_MeshAlgos::TFreeBorder& nodes = cfb._borders[i]; + SMESH::FreeBorder& aBRD = aCFB->borders[i]; + aBRD.nodeIDs.length( nodes.size() ); + for ( size_t iN = 0; iN < nodes.size(); ++iN ) + aBRD.nodeIDs[ iN ] = nodes[ iN ]->GetID(); + } + + // copy coincident parts + aCFB->coincidentGroups.length( cfb._coincidentGroups.size() ); + for ( size_t i = 0; i < cfb._coincidentGroups.size(); ++i ) + { + SMESH_MeshAlgos::TCoincidentGroup& grp = cfb._coincidentGroups[i]; + SMESH::FreeBordersGroup& aGRP = aCFB->coincidentGroups[i]; + aGRP.length( grp.size() ); + for ( size_t iP = 0; iP < grp.size(); ++iP ) + { + SMESH_MeshAlgos::TFreeBorderPart& part = grp[ iP ]; + SMESH::FreeBorderPart& aPART = aGRP[ iP ]; + aPART.border = part._border; + aPART.node1 = part._node1; + aPART.node2 = part._node2; + aPART.nodeLast = part._nodeLast; + } + } + SMESH_CATCH( SMESH::doNothing ); + + TPythonDump() << "CoincidentFreeBorders = " + << this << ".FindCoincidentFreeBorders( " << tolerance << " )"; + + return aCFB._retn(); +} + +//======================================================================= +/*! + * Sew FreeBorder's of each group + */ +//======================================================================= + +CORBA::Short SMESH_MeshEditor_i:: +SewCoincidentFreeBorders(const SMESH::CoincidentFreeBorders& freeBorders, + CORBA::Boolean createPolygons, + CORBA::Boolean createPolyhedra) +{ + CORBA::Short nbSewed = 0; + + SMESH_MeshAlgos::TFreeBorderVec groups; + SMESH_MeshAlgos::TFreeBorder borderNodes; // triples of nodes for every FreeBorderPart + + // check the input and collect nodes + for ( CORBA::ULong i = 0; i < freeBorders.coincidentGroups.length(); ++i ) + { + borderNodes.clear(); + const SMESH::FreeBordersGroup& aGRP = freeBorders.coincidentGroups[ i ]; + for ( CORBA::ULong iP = 0; iP < aGRP.length(); ++iP ) + { + const SMESH::FreeBorderPart& aPART = aGRP[ iP ]; + if ( aPART.border < 0 || aPART.border >= (int) freeBorders.borders.length() ) + THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::border index", SALOME::BAD_PARAM); + + const SMESH::FreeBorder& aBRD = freeBorders.borders[ aPART.border ]; + + if ( aPART.node1 < 0 || aPART.node1 > (int) aBRD.nodeIDs.length() ) + THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::node1", SALOME::BAD_PARAM); + if ( aPART.node2 < 0 || aPART.node2 > (int) aBRD.nodeIDs.length() ) + THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::node2", SALOME::BAD_PARAM); + if ( aPART.nodeLast < 0 || aPART.nodeLast > (int) aBRD.nodeIDs.length() ) + THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::nodeLast", SALOME::BAD_PARAM); + + // do not keep these nodes for further sewing as nodes can be removed by the sewing + const SMDS_MeshNode* n1 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node1 ]); + const SMDS_MeshNode* n2 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node2 ]); + const SMDS_MeshNode* n3 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.nodeLast ]); + if ( !n1) + THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::node1", SALOME::BAD_PARAM); + if ( !n2 ) + THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::node2", SALOME::BAD_PARAM); + if ( !n3 ) + THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::nodeLast", SALOME::BAD_PARAM); + + borderNodes.push_back( n1 ); + borderNodes.push_back( n2 ); + borderNodes.push_back( n3 ); + } + groups.push_back( borderNodes ); + } + + // SewFreeBorder() can merge nodes, thus nodes stored in 'groups' can become dead; + // to get nodes that replace other nodes during merge we create 0D elements + // on each node and MergeNodes() will replace underlying nodes of 0D elements by + // new ones. + + vector< const SMDS_MeshElement* > tmp0Delems; + for ( size_t i = 0; i < groups.size(); ++i ) + { + SMESH_MeshAlgos::TFreeBorder& nodes = groups[i]; + for ( size_t iN = 0; iN < nodes.size(); ++iN ) + { + SMDS_ElemIteratorPtr it0D = nodes[iN]->GetInverseElementIterator(SMDSAbs_0DElement); + if ( it0D->more() ) + tmp0Delems.push_back( it0D->next() ); + else + tmp0Delems.push_back( getMeshDS()->Add0DElement( nodes[iN] )); + } + } + + // cout << endl << "INIT" << endl; + // for ( size_t i = 0; i < tmp0Delems.size(); ++i ) + // { + // cout << i << " "; + // if ( i % 3 == 0 ) cout << "^ "; + // tmp0Delems[i]->GetNode(0)->Print( cout ); + // } + + SMESH_TRY; + + ::SMESH_MeshEditor::Sew_Error res, ok = ::SMESH_MeshEditor::SEW_OK; + int i0D = 0; + for ( size_t i = 0; i < groups.size(); ++i ) + { + bool isBordToBord = true; + bool groupSewed = false; + SMESH_MeshAlgos::TFreeBorder& nodes = groups[i]; + for ( size_t iN = 3; iN+2 < nodes.size(); iN += 3 ) + { + const SMDS_MeshNode* n0 = tmp0Delems[ i0D + 0 ]->GetNode( 0 ); + const SMDS_MeshNode* n1 = tmp0Delems[ i0D + 1 ]->GetNode( 0 ); + const SMDS_MeshNode* n2 = tmp0Delems[ i0D + 2 ]->GetNode( 0 ); + + const SMDS_MeshNode* n3 = tmp0Delems[ i0D + 0 + iN ]->GetNode( 0 ); + const SMDS_MeshNode* n4 = tmp0Delems[ i0D + 1 + iN ]->GetNode( 0 ); + const SMDS_MeshNode* n5 = tmp0Delems[ i0D + 2 + iN ]->GetNode( 0 ); + + if ( !n0 || !n1 || !n2 || !n3 || !n4 || !n5 ) + continue; + + // TIDSortedElemSet emptySet, avoidSet; + // if ( !SMESH_MeshAlgos::FindFaceInSet( n0, n1, emptySet, avoidSet)) + // { + // cout << "WRONG 2nd 1" << endl; + // n0->Print( cout ); + // n1->Print( cout ); + // } + // if ( !SMESH_MeshAlgos::FindFaceInSet( n3, n4, emptySet, avoidSet)) + // { + // cout << "WRONG 2nd 2" << endl; + // n3->Print( cout ); + // n4->Print( cout ); + // } + + if ( !isBordToBord ) + { + n1 = n2; // at border-to-side sewing only last side node (n1) is needed + n2 = 0; // and n2 is not used + } + // 1st border moves to 2nd + res = getEditor().SewFreeBorder( n3, n4, n5 ,// 1st + n0 ,n1 ,n2 ,// 2nd + /*2ndIsFreeBorder=*/ isBordToBord, + createPolygons, createPolyhedra); + groupSewed = ( res == ok ); + + isBordToBord = false; + // cout << endl << "SEWED GROUP " << i << " PART " << iN / 3 << endl; + // for ( size_t t = 0; t < tmp0Delems.size(); ++t ) + // { + // cout << t << " "; + // if ( t % 3 == 0 ) cout << "^ "; + // tmp0Delems[t]->GetNode(0)->Print( cout ); + // } + } + i0D += nodes.size(); + nbSewed += groupSewed; + } + + TPythonDump() << "nbSewed = " << this << ".SewCoincidentFreeBorders( " + << freeBorders << ", " + << createPolygons << ", " + << createPolyhedra << " )"; + + SMESH_CATCH( SMESH::doNothing ); + + declareMeshModified( /*isReComputeSafe=*/false ); + + // remove tmp 0D elements + SMESH_TRY; + set< const SMDS_MeshElement* > removed0D; + for ( size_t i = 0; i < tmp0Delems.size(); ++i ) + { + if ( removed0D.insert( tmp0Delems[i] ).second ) + getMeshDS()->RemoveFreeElement( tmp0Delems[i], /*sm=*/0, /*fromGroups=*/false ); + } + SMESH_CATCH( SMESH::throwCorbaException ); + + return nbSewed; +} + //======================================================================= //function : SewFreeBorders //purpose : //======================================================================= SMESH::SMESH_MeshEditor::Sew_Error -SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1, - CORBA::Long SecondNodeID1, - CORBA::Long LastNodeID1, - CORBA::Long FirstNodeID2, - CORBA::Long SecondNodeID2, - CORBA::Long LastNodeID2, - CORBA::Boolean CreatePolygons, - CORBA::Boolean CreatePolyedrs) - throw (SALOME::SALOME_Exception) +SMESH_MeshEditor_i::SewFreeBorders(SMESH::smIdType FirstNodeID1, + SMESH::smIdType SecondNodeID1, + SMESH::smIdType LastNodeID1, + SMESH::smIdType FirstNodeID2, + SMESH::smIdType SecondNodeID2, + SMESH::smIdType LastNodeID2, + CORBA::Boolean CreatePolygons, + CORBA::Boolean CreatePolyedrs) { SMESH_TRY; initData(); @@ -5340,14 +5318,14 @@ SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1, SMESH::SMESH_MeshEditor::Sew_Error error = convError( getEditor().SewFreeBorder (aBorderFirstNode, - aBorderSecondNode, - aBorderLastNode, - aSide2FirstNode, - aSide2SecondNode, - aSide2ThirdNode, - true, - CreatePolygons, - CreatePolyedrs) ); + aBorderSecondNode, + aBorderLastNode, + aSide2FirstNode, + aSide2SecondNode, + aSide2ThirdNode, + true, + CreatePolygons, + CreatePolyedrs) ); declareMeshModified( /*isReComputeSafe=*/false ); @@ -5364,12 +5342,11 @@ SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1, //======================================================================= SMESH::SMESH_MeshEditor::Sew_Error -SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1, - CORBA::Long SecondNodeID1, - CORBA::Long LastNodeID1, - CORBA::Long FirstNodeID2, - CORBA::Long SecondNodeID2) - throw (SALOME::SALOME_Exception) +SMESH_MeshEditor_i::SewConformFreeBorders(SMESH::smIdType FirstNodeID1, + SMESH::smIdType SecondNodeID1, + SMESH::smIdType LastNodeID1, + SMESH::smIdType FirstNodeID2, + SMESH::smIdType SecondNodeID2) { SMESH_TRY; initData(); @@ -5400,13 +5377,13 @@ SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1, SMESH::SMESH_MeshEditor::Sew_Error error = convError( getEditor().SewFreeBorder (aBorderFirstNode, - aBorderSecondNode, - aBorderLastNode, - aSide2FirstNode, - aSide2SecondNode, - aSide2ThirdNode, - true, - false, false) ); + aBorderSecondNode, + aBorderLastNode, + aSide2FirstNode, + aSide2SecondNode, + aSide2ThirdNode, + true, + false, false) ); declareMeshModified( /*isReComputeSafe=*/false ); return error; @@ -5422,14 +5399,13 @@ SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1, //======================================================================= SMESH::SMESH_MeshEditor::Sew_Error -SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder, - CORBA::Long SecondNodeIDOnFreeBorder, - CORBA::Long LastNodeIDOnFreeBorder, - CORBA::Long FirstNodeIDOnSide, - CORBA::Long LastNodeIDOnSide, - CORBA::Boolean CreatePolygons, - CORBA::Boolean CreatePolyedrs) - throw (SALOME::SALOME_Exception) +SMESH_MeshEditor_i::SewBorderToSide(SMESH::smIdType FirstNodeIDOnFreeBorder, + SMESH::smIdType SecondNodeIDOnFreeBorder, + SMESH::smIdType LastNodeIDOnFreeBorder, + SMESH::smIdType FirstNodeIDOnSide, + SMESH::smIdType LastNodeIDOnSide, + CORBA::Boolean CreatePolygons, + CORBA::Boolean CreatePolyedrs) { SMESH_TRY; initData(); @@ -5462,14 +5438,14 @@ SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder, SMESH::SMESH_MeshEditor::Sew_Error error = convError( getEditor().SewFreeBorder (aBorderFirstNode, - aBorderSecondNode, - aBorderLastNode, - aSide2FirstNode, - aSide2SecondNode, - aSide2ThirdNode, - false, - CreatePolygons, - CreatePolyedrs) ); + aBorderSecondNode, + aBorderLastNode, + aSide2FirstNode, + aSide2SecondNode, + aSide2ThirdNode, + false, + CreatePolygons, + CreatePolyedrs) ); declareMeshModified( /*isReComputeSafe=*/false ); return error; @@ -5485,13 +5461,12 @@ SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder, //======================================================================= SMESH::SMESH_MeshEditor::Sew_Error -SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements, - const SMESH::long_array& IDsOfSide2Elements, - CORBA::Long NodeID1OfSide1ToMerge, - CORBA::Long NodeID1OfSide2ToMerge, - CORBA::Long NodeID2OfSide1ToMerge, - CORBA::Long NodeID2OfSide2ToMerge) - throw (SALOME::SALOME_Exception) +SMESH_MeshEditor_i::SewSideElements(const SMESH::smIdType_array& IDsOfSide1Elements, + const SMESH::smIdType_array& IDsOfSide2Elements, + SMESH::smIdType NodeID1OfSide1ToMerge, + SMESH::smIdType NodeID1OfSide2ToMerge, + SMESH::smIdType NodeID2OfSide1ToMerge, + SMESH::smIdType NodeID2OfSide2ToMerge) { SMESH_TRY; initData(); @@ -5545,32 +5520,27 @@ SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements, */ //================================================================================ -CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide, - const SMESH::long_array& newIDs) - throw (SALOME::SALOME_Exception) +CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(SMESH::smIdType ide, + const SMESH::smIdType_array& newIDs) { SMESH_TRY; initData(); const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide); - if(!elem) return false; + if ( !elem ) return false; int nbn = newIDs.length(); - int i=0; vector aNodes(nbn); - int nbn1=-1; - for(; iFindNode(newIDs[i]); - if(aNode) { - nbn1++; - aNodes[nbn1] = aNode; - } + for ( int i = 0; i < nbn; i++ ) { + const SMDS_MeshNode* aNode = getMeshDS()->FindNode( newIDs[ i ]); + if ( !aNode ) + return false; + aNodes[ i ] = aNode; } TPythonDump() << "isDone = " << this << ".ChangeElemNodes( " << ide << ", " << newIDs << " )"; - MESSAGE("ChangeElementNodes"); - bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 ); + bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], aNodes.size() ); declareMeshModified( /*isReComputeSafe=*/ !res ); @@ -5589,16 +5559,16 @@ CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide, void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d, CORBA::Boolean theToBiQuad, SMESH::SMESH_IDSource_ptr theObject) - throw (SALOME::SALOME_Exception) { SMESH_TRY; + initData(); + TIDSortedElemSet elems; bool elemsOK; if ( !( elemsOK = CORBA::is_nil( theObject ))) { - prepareIdSource( theObject ); - elemsOK = idSourceToSet( theObject, getMeshDS(), elems, - SMDSAbs_All, /*emptyIfIsMesh=*/true ); + elemsOK = idSourceToSet( theObject, getMeshDS(), elems, + SMDSAbs_All, /*emptyIfIsMesh=*/true ); } if ( elemsOK ) { @@ -5620,12 +5590,17 @@ void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d //======================================================================= CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic() - throw (SALOME::SALOME_Exception) { + SMESH_TRY; + initData(); + CORBA::Boolean isDone = getEditor().ConvertFromQuadratic(); TPythonDump() << this << ".ConvertFromQuadratic()"; declareMeshModified( /*isReComputeSafe=*/!isDone ); return isDone; + + SMESH_CATCH( SMESH::throwCorbaException ); + return false; } //======================================================================= @@ -5634,7 +5609,6 @@ CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic() //======================================================================= void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d) - throw (SALOME::SALOME_Exception) { convertToQuadratic( theForce3d, false ); TPythonDump() << this << ".ConvertToQuadratic("<CreateEmptyMesh(); - SALOMEDS::Study_var study = gen->GetCurrentStudy(); - SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh ); + SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( mesh ); gen->SetName( meshSO, theMeshName, "Mesh" ); gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED"); @@ -5743,10 +5713,10 @@ void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPytho */ //================================================================================ -string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix) +std::string SMESH_MeshEditor_i::GenerateGroupName(const std::string& thePrefix) { SMESH::ListOfGroups_var groups = myMesh_i->GetGroups(); - set groupNames; + set groupNames; // Get existing group names for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) { @@ -5759,7 +5729,7 @@ string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix) } // Find new name - string name = thePrefix; + std::string name = thePrefix; int index = 0; while (!groupNames.insert(name).second) @@ -5782,15 +5752,84 @@ void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject) filter->SetMesh( mesh ); } } +//================================================================================ +/*! + * \brief Retrieve elements of given type from SMESH_IDSource + */ +//================================================================================ + +bool SMESH_MeshEditor_i::idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource, + const SMESHDS_Mesh* theMeshDS, + TIDSortedElemSet& theElemSet, + const SMDSAbs_ElementType theType, + const bool emptyIfIsMesh, + IDSource_Error* error) + +{ + if ( error ) *error = IDSource_OK; + + if ( CORBA::is_nil( theIDSource )) + { + if ( error ) *error = IDSource_INVALID; + return false; + } + if ( emptyIfIsMesh && SMESH::DownCast( theIDSource )) + { + if ( error && theMeshDS->GetMeshInfo().NbElements( theType ) == 0 ) + *error = IDSource_EMPTY; + return true; + } + if ( getMeshDS() == theMeshDS ) // check if theIDSource belongs to myMesh + { + SMESH::SMESH_Mesh_var mesh = theIDSource->GetMesh(); + SMESH_Mesh_i* mesh_i = SMESH::DownCast( mesh ); + if ( mesh_i && mesh_i != myMesh_i ) + { + if ( error ) + *error = IDSource_INVALID; + return false; + } + } + prepareIdSource( theIDSource ); + SMESH::smIdType_array_var anIDs = theIDSource->GetIDs(); + if ( anIDs->length() == 0 ) + { + if ( error ) *error = IDSource_EMPTY; + return false; + } + SMESH::array_of_ElementType_var types = theIDSource->GetTypes(); + if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes + { + if ( theType == SMDSAbs_All || theType == SMDSAbs_Node ) + { + arrayToSet( anIDs, getMeshDS(), theElemSet, SMDSAbs_Node ); + } + else + { + if ( error ) *error = IDSource_INVALID; + return false; + } + } + else + { + arrayToSet( anIDs, getMeshDS(), theElemSet, theType); + if ( bool(anIDs->length()) != bool(theElemSet.size())) + { + if ( error ) *error = IDSource_INVALID; + return false; + } + } + return true; +} //================================================================================ /*! - * \brief Duplicates given elements, i.e. creates new elements based on the + * \brief Duplicates given elements, i.e. creates new elements based on the * same nodes as the given ones. * \param theElements - container of elements to duplicate. * \param theGroupName - a name of group to contain the generated elements. * If a group with such a name already exists, the new elements - * are added to the existng group, else a new group is created. + * are added to the existing group, else a new group is created. * If \a theGroupName is empty, new elements are not added * in any group. * \return a group where the new elements are added. NULL if theGroupName == "". @@ -5801,7 +5840,6 @@ void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject) SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements, const char* theGroupName) - throw (SALOME::SALOME_Exception) { SMESH::SMESH_Group_var newGroup; @@ -5811,16 +5849,15 @@ SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements, TPythonDump pyDump; TIDSortedElemSet elems; - prepareIdSource( theElements ); if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true)) { getEditor().DoubleElements( elems ); - if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() ) + if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().empty() ) { // group type SMESH::ElementType type = - SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() ); + SMESH::ElementType( getEditor().GetLastCreatedElems()[0]->GetType() ); // find existing group SMESH::ListOfGroups_var groups = myMesh_i->GetGroups(); for ( size_t i = 0; i < groups->length(); ++i ) @@ -5840,8 +5877,8 @@ SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements, { SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() ); const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems(); - for ( int i = 1; i <= aSeq.Length(); i++ ) - groupDS->SMDSGroup().Add( aSeq(i) ); + for ( size_t i = 0; i < aSeq.size(); i++ ) + groupDS->SMDSGroup().Add( aSeq[i] ); } } } @@ -5868,9 +5905,8 @@ SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements, */ //================================================================================ -CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes, - const SMESH::long_array& theModifiedElems ) - throw (SALOME::SALOME_Exception) +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::smIdType_array& theNodes, + const SMESH::smIdType_array& theModifiedElems ) { SMESH_TRY; initData(); @@ -5908,12 +5944,11 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNode */ //================================================================================ -CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId, - const SMESH::long_array& theModifiedElems ) - throw (SALOME::SALOME_Exception) +CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( SMESH::smIdType theNodeId, + const SMESH::smIdType_array& theModifiedElems ) { SMESH_TRY; - SMESH::long_array_var aNodes = new SMESH::long_array; + SMESH::smIdType_array_var aNodes = new SMESH::smIdType_array; aNodes->length( 1 ); aNodes[ 0 ] = theNodeId; @@ -5942,21 +5977,17 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeI CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes, SMESH::SMESH_GroupBase_ptr theModifiedElems ) - throw (SALOME::SALOME_Exception) { SMESH_TRY; if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE ) return false; - SMESH::long_array_var aNodes = theNodes->GetListOfID(); - SMESH::long_array_var aModifiedElems; + SMESH::smIdType_array_var aNodes = theNodes->GetListOfID(); + SMESH::smIdType_array_var aModifiedElems; if ( !CORBA::is_nil( theModifiedElems ) ) aModifiedElems = theModifiedElems->GetListOfID(); else - { - aModifiedElems = new SMESH::long_array; - aModifiedElems->length( 0 ); - } + aModifiedElems = new SMESH::smIdType_array; TPythonDump pyDump; // suppress dump by the next line @@ -5984,7 +6015,6 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr th SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes, SMESH::SMESH_GroupBase_ptr theModifiedElems ) - throw (SALOME::SALOME_Exception) { SMESH_TRY; SMESH::SMESH_Group_var aNewGroup; @@ -5993,12 +6023,12 @@ SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes, return aNewGroup._retn(); // Duplicate nodes - SMESH::long_array_var aNodes = theNodes->GetListOfID(); - SMESH::long_array_var aModifiedElems; + SMESH::smIdType_array_var aNodes = theNodes->GetListOfID(); + SMESH::smIdType_array_var aModifiedElems; if ( !CORBA::is_nil( theModifiedElems ) ) aModifiedElems = theModifiedElems->GetListOfID(); else { - aModifiedElems = new SMESH::long_array; + aModifiedElems = new SMESH::smIdType_array; aModifiedElems->length( 0 ); } @@ -6008,10 +6038,10 @@ SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes, if ( aResult ) { // Create group with newly created nodes - SMESH::long_array_var anIds = GetLastCreatedNodes(); + SMESH::smIdType_array_var anIds = GetLastCreatedNodes(); if (anIds->length() > 0) { - string anUnindexedName (theNodes->GetName()); - string aNewName = generateGroupName(anUnindexedName + "_double"); + std::string anUnindexedName (theNodes->GetName()); + std::string aNewName = GenerateGroupName(anUnindexedName + "_double"); aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str()); aNewGroup->Add(anIds); pyDump << aNewGroup << " = "; @@ -6040,19 +6070,18 @@ SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes, CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes, const SMESH::ListOfGroups& theModifiedElems ) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); std::list< int > aNodes; - int i, n, j, m; + smIdType i, n, j, m; for ( i = 0, n = theNodes.length(); i < n; i++ ) { SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ]; if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE ) { - SMESH::long_array_var aCurr = aGrp->GetListOfID(); + SMESH::smIdType_array_var aCurr = aGrp->GetListOfID(); for ( j = 0, m = aCurr->length(); j < m; j++ ) aNodes.push_back( aCurr[ j ] ); } @@ -6064,7 +6093,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& t SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ]; if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE ) { - SMESH::long_array_var aCurr = aGrp->GetListOfID(); + SMESH::smIdType_array_var aCurr = aGrp->GetListOfID(); for ( j = 0, m = aCurr->length(); j < m; j++ ) anElems.push_back( aCurr[ j ] ); } @@ -6096,7 +6125,6 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& t SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes, const SMESH::ListOfGroups& theModifiedElems ) - throw (SALOME::SALOME_Exception) { SMESH::SMESH_Group_var aNewGroup; @@ -6107,10 +6135,10 @@ SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes, if ( aResult ) { // Create group with newly created nodes - SMESH::long_array_var anIds = GetLastCreatedNodes(); + SMESH::smIdType_array_var anIds = GetLastCreatedNodes(); if (anIds->length() > 0) { - string anUnindexedName (theNodes[0]->GetName()); - string aNewName = generateGroupName(anUnindexedName + "_double"); + std::string anUnindexedName (theNodes[0]->GetName()); + std::string aNewName = GenerateGroupName(anUnindexedName + "_double"); aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str()); aNewGroup->Add(anIds); pyDump << aNewGroup << " = "; @@ -6137,10 +6165,9 @@ SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes, */ //================================================================================ -CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems, - const SMESH::long_array& theNodesNot, - const SMESH::long_array& theAffectedElems ) - throw (SALOME::SALOME_Exception) +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::smIdType_array& theElems, + const SMESH::smIdType_array& theNodesNot, + const SMESH::smIdType_array& theAffectedElems ) { SMESH_TRY; initData(); @@ -6178,10 +6205,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theE */ //================================================================================ -CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems, - const SMESH::long_array& theNodesNot, - GEOM::GEOM_Object_ptr theShape ) - throw (SALOME::SALOME_Exception) +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::smIdType_array& theElems, + const SMESH::smIdType_array& theNodesNot, + GEOM::GEOM_Object_ptr theShape ) { SMESH_TRY; initData(); @@ -6222,7 +6248,6 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems, SMESH::SMESH_GroupBase_ptr theNodesNot, SMESH::SMESH_GroupBase_ptr theAffectedElems) - throw (SALOME::SALOME_Exception) { SMESH_TRY; if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE ) @@ -6267,7 +6292,6 @@ SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems, SMESH::SMESH_GroupBase_ptr theNodesNot, SMESH::SMESH_GroupBase_ptr theAffectedElems) - throw (SALOME::SALOME_Exception) { TPythonDump pyDump; SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems, @@ -6304,7 +6328,6 @@ SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems, SMESH::SMESH_GroupBase_ptr theAffectedElems, CORBA::Boolean theElemGroupNeeded, CORBA::Boolean theNodeGroupNeeded) - throw (SALOME::SALOME_Exception) { SMESH_TRY; SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup; @@ -6334,17 +6357,17 @@ SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems, { // Create group with newly created elements CORBA::String_var elemGroupName = theElems->GetName(); - string aNewName = generateGroupName( string(elemGroupName.in()) + "_double"); - if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded ) + std::string aNewName = GenerateGroupName( std::string(elemGroupName.in()) + "_double"); + if ( !getEditor().GetLastCreatedElems().empty() && theElemGroupNeeded ) { - SMESH::long_array_var anIds = GetLastCreatedElems(); + SMESH::smIdType_array_var anIds = GetLastCreatedElems(); SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true); aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str()); aNewElemGroup->Add(anIds); } - if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded ) + if ( !getEditor().GetLastCreatedNodes().empty() && theNodeGroupNeeded ) { - SMESH::long_array_var anIds = GetLastCreatedNodes(); + SMESH::smIdType_array_var anIds = GetLastCreatedNodes(); aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str()); aNewNodeGroup->Add(anIds); } @@ -6389,7 +6412,6 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems, SMESH::SMESH_GroupBase_ptr theNodesNot, GEOM::GEOM_Object_ptr theShape ) - throw (SALOME::SALOME_Exception) { SMESH_TRY; if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE ) @@ -6439,7 +6461,7 @@ static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList, if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE : aGrp->GetType() != SMESH::NODE ) ) { - SMESH::long_array_var anIDs = aGrp->GetIDs(); + SMESH::smIdType_array_var anIDs = aGrp->GetIDs(); arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All ); } } @@ -6462,7 +6484,6 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems, const SMESH::ListOfGroups& theNodesNot, const SMESH::ListOfGroups& theAffectedElems) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -6504,7 +6525,6 @@ SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems, const SMESH::ListOfGroups& theNodesNot, const SMESH::ListOfGroups& theAffectedElems) - throw (SALOME::SALOME_Exception) { TPythonDump pyDump; SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems, @@ -6541,7 +6561,6 @@ SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems const SMESH::ListOfGroups& theAffectedElems, CORBA::Boolean theElemGroupNeeded, CORBA::Boolean theNodeGroupNeeded) - throw (SALOME::SALOME_Exception) { SMESH_TRY; SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup; @@ -6566,17 +6585,17 @@ SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems { // Create group with newly created elements CORBA::String_var elemGroupName = theElems[0]->GetName(); - string aNewName = generateGroupName( string(elemGroupName.in()) + "_double"); - if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded ) + std::string aNewName = GenerateGroupName( std::string(elemGroupName.in()) + "_double"); + if ( !getEditor().GetLastCreatedElems().empty() && theElemGroupNeeded ) { - SMESH::long_array_var anIds = GetLastCreatedElems(); + SMESH::smIdType_array_var anIds = GetLastCreatedElems(); SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true); aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str()); aNewElemGroup->Add(anIds); } - if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded ) + if ( !getEditor().GetLastCreatedNodes().empty() && theNodeGroupNeeded ) { - SMESH::long_array_var anIds = GetLastCreatedNodes(); + SMESH::smIdType_array_var anIds = GetLastCreatedNodes(); aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str()); aNewNodeGroup->Add(anIds); } @@ -6622,7 +6641,6 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems, const SMESH::ListOfGroups& theNodesNot, GEOM::GEOM_Object_ptr theShape ) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -6653,7 +6671,7 @@ SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theE duplication is not performed. This method is the first step of DoubleNodeElemGroupsInRegion. \param theElems - list of groups of elements (edges or faces) to be replicated - \param theNodesNot - list of groups of nodes not to replicated + \param theNodesNot - list of groups of nodes not to replicate \param theShape - shape to detect affected elements (element which geometric center located on or inside shape). The replicated nodes should be associated to affected elements. @@ -6665,17 +6683,12 @@ SMESH::ListOfGroups* SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems, const SMESH::ListOfGroups& theNodesNot, GEOM::GEOM_Object_ptr theShape ) - throw (SALOME::SALOME_Exception) { SMESH_TRY; - MESSAGE("AffectedElemGroupsInRegion"); SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups(); - bool isEdgeGroup = false; - bool isFaceGroup = false; - bool isVolumeGroup = false; - SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges"); - SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces"); - SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes"); + SMESH::SMESH_Group_var aNewEdgeGroup = SMESH::SMESH_Group::_nil(); + SMESH::SMESH_Group_var aNewFaceGroup = SMESH::SMESH_Group::_nil(); + SMESH::SMESH_Group_var aNewVolumeGroup = SMESH::SMESH_Group::_nil(); initData(); @@ -6683,76 +6696,75 @@ SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theEl SMESHDS_Mesh* aMeshDS = getMeshDS(); TIDSortedElemSet anElems, aNodes; - listOfGroupToSet(theElems, aMeshDS, anElems, false); + bool isNodeGrp = theElems.length() ? theElems[0]->GetType() == SMESH::NODE : false; + listOfGroupToSet(theElems, aMeshDS, anElems, isNodeGrp); listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true); TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape); TIDSortedElemSet anAffected; bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected); - declareMeshModified( /*isReComputeSafe=*/ !aResult ); TPythonDump pyDump; - if (aResult) - { - int lg = anAffected.size(); - MESSAGE("lg="<< lg); - SMESH::long_array_var volumeIds = new SMESH::long_array; - volumeIds->length(lg); - SMESH::long_array_var faceIds = new SMESH::long_array; - faceIds->length(lg); - SMESH::long_array_var edgeIds = new SMESH::long_array; - edgeIds->length(lg); + if ( aResult && anAffected.size() > 0 ) + { + SMESH::smIdType_array_var volumeIds = new SMESH::smIdType_array; + SMESH::smIdType_array_var faceIds = new SMESH::smIdType_array; + SMESH::smIdType_array_var edgeIds = new SMESH::smIdType_array; + volumeIds->length( anAffected.size() ); + faceIds ->length( anAffected.size() ); + edgeIds ->length( anAffected.size() ); + int ivol = 0; int iface = 0; int iedge = 0; - TIDSortedElemSet::const_iterator eIt = anAffected.begin(); for (; eIt != anAffected.end(); ++eIt) { const SMDS_MeshElement* anElem = *eIt; - if (!anElem) - continue; - int elemId = anElem->GetID(); - if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume) - volumeIds[ivol++] = elemId; - else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face) - faceIds[iface++] = elemId; - else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge) - edgeIds[iedge++] = elemId; + smIdType elemId = anElem->GetID(); + switch ( anElem->GetType() ) { + case SMDSAbs_Volume: volumeIds[ivol++] = elemId; break; + case SMDSAbs_Face: faceIds[iface++] = elemId; break; + case SMDSAbs_Edge: edgeIds[iedge++] = elemId; break; + default:; + } } volumeIds->length(ivol); faceIds->length(iface); edgeIds->length(iedge); - aNewVolumeGroup->Add(volumeIds); - aNewFaceGroup->Add(faceIds); - aNewEdgeGroup->Add(edgeIds); - isVolumeGroup = (aNewVolumeGroup->Size() > 0); - isFaceGroup = (aNewFaceGroup->Size() > 0); - isEdgeGroup = (aNewEdgeGroup->Size() > 0); + int nbGroups = 0; + if ( ivol > 0 ) + { + aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, + GenerateGroupName("affectedVolumes").c_str()); + aNewVolumeGroup->Add(volumeIds); + aListOfGroups->length( nbGroups+1 ); + aListOfGroups[ nbGroups++ ] = aNewVolumeGroup._retn(); + } + if ( iface > 0 ) + { + aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, + GenerateGroupName("affectedFaces").c_str()); + aNewFaceGroup->Add(faceIds); + aListOfGroups->length( nbGroups+1 ); + aListOfGroups[ nbGroups++ ] = aNewFaceGroup._retn(); + } + if ( iedge > 0 ) + { + aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, + GenerateGroupName("affectedEdges").c_str()); + aNewEdgeGroup->Add(edgeIds); + aListOfGroups->length( nbGroups+1 ); + aListOfGroups[ nbGroups++ ] = aNewEdgeGroup._retn(); + } } - int nbGroups = 0; - if (isEdgeGroup) nbGroups++; - if (isFaceGroup) nbGroups++; - if (isVolumeGroup) nbGroups++; - aListOfGroups->length(nbGroups); - - int i = 0; - if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn(); - if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn(); - if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn(); - // Update Python script - pyDump << "[ "; - if (isEdgeGroup) pyDump << aNewEdgeGroup << ", "; - if (isFaceGroup) pyDump << aNewFaceGroup << ", "; - if (isVolumeGroup) pyDump << aNewVolumeGroup << ", "; - pyDump << "] = "; - pyDump << this << ".AffectedElemGroupsInRegion( " + pyDump << aListOfGroups << " = " << this << ".AffectedElemGroupsInRegion( " << &theElems << ", " << &theNodesNot << ", " << theShape << " )"; return aListOfGroups._retn(); @@ -6764,13 +6776,12 @@ SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theEl //================================================================================ /*! \brief Generated skin mesh (containing 2D cells) from 3D mesh - The created 2D mesh elements based on nodes of free faces of boundary volumes + The created 2D mesh elements based on nodes of free faces of boundary volumes \return TRUE if operation has been completed successfully, FALSE otherwise */ //================================================================================ CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D() - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -6800,18 +6811,20 @@ CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D() * If there is no shared faces between the group #n and the group #p in the list, the group j_n_p is not created. * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation). * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples". - * @param theDomains - list of groups of volumes - * @param createJointElems - if TRUE, create the elements - * @return TRUE if operation has been completed successfully, FALSE otherwise + * \param theDomains - list of groups of volumes + * \param createJointElems - if TRUE, create the elements + * \param onAllBoundaries - if TRUE, the nodes and elements are also created on + * the boundary between \a theDomains and the rest mesh + * \return TRUE if operation has been completed successfully, FALSE otherwise */ //================================================================================ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains, - CORBA::Boolean createJointElems ) - throw (SALOME::SALOME_Exception) + CORBA::Boolean createJointElems, + CORBA::Boolean onAllBoundaries ) { - bool aResult = false; + bool isOK = false; SMESH_TRY; initData(); @@ -6819,10 +6832,11 @@ SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& the SMESHDS_Mesh* aMeshDS = getMeshDS(); // MESSAGE("theDomains.length = "< domains; - domains.clear(); + domains.resize( theDomains.length() ); for ( int i = 0, n = theDomains.length(); i < n; i++ ) { @@ -6831,26 +6845,25 @@ SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& the { // if ( aGrp->GetType() != SMESH::VOLUME ) // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM); - TIDSortedElemSet domain; - domain.clear(); - domains.push_back(domain); - SMESH::long_array_var anIDs = aGrp->GetIDs(); + SMESH::smIdType_array_var anIDs = aGrp->GetIDs(); arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All ); } } - aResult = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems ); + isOK = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems, onAllBoundaries ); // TODO publish the groups of flat elements in study - declareMeshModified( /*isReComputeSafe=*/ !aResult ); + declareMeshModified( /*isReComputeSafe=*/ !isOK ); // Update Python script TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains - << ", " << createJointElems << " )"; + << ", " << createJointElems << ", " << onAllBoundaries << " )"; SMESH_CATCH( SMESH::throwCorbaException ); - return aResult; + myMesh_i->CreateGroupServants(); // publish created groups if any + + return isOK; } //================================================================================ @@ -6867,7 +6880,6 @@ SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& the CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces ) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -6885,7 +6897,7 @@ SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& TIDSortedElemSet faceGroup; faceGroup.clear(); faceGroups.push_back(faceGroup); - SMESH::long_array_var anIDs = aGrp->GetIDs(); + SMESH::smIdType_array_var anIDs = aGrp->GetIDs(); arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All ); } } @@ -6920,7 +6932,6 @@ void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius, const char* groupName, const SMESH::double_array& theNodesCoords, SMESH::array_of_long_array_out GroupsOfNodes) - throw (SALOME::SALOME_Exception) { SMESH_TRY; @@ -6933,7 +6944,7 @@ void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius, theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() ); vector nodesCoords; - for (int i = 0; i < theNodesCoords.length(); i++) + for ( CORBA::ULong i = 0; i < theNodesCoords.length(); i++) { nodesCoords.push_back( theNodesCoords[i] ); } @@ -6988,7 +6999,6 @@ SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource, CORBA::Boolean toCopyElements, CORBA::Boolean toCopyExistingBondary, SMESH::SMESH_Group_out group) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -7005,7 +7015,6 @@ SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource, TIDSortedElemSet elements; SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume; - prepareIdSource( idSource ); if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true )) { // mesh to fill in @@ -7044,7 +7053,7 @@ SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource, else pyDump << mesh_var << ", "; if ( group_var->_is_nil() ) - pyDump << "_NoneGroup = "; // assignment to None is forbiden + pyDump << "_NoneGroup = "; // assignment to None is forbidden else pyDump << group_var << " = "; pyDump << this << ".MakeBoundaryMesh( " @@ -7086,7 +7095,6 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim, const SMESH::ListOfIDSources& groups, SMESH::SMESH_Mesh_out mesh, SMESH::SMESH_Group_out group) - throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); @@ -7095,20 +7103,20 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim, THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM); // separate groups belonging to this and other mesh - SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources; + SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources; SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources; - groupsOfThisMesh->length( groups.length() ); + groupsOfThisMesh ->length( groups.length() ); groupsOfOtherMesh->length( groups.length() ); int nbGroups = 0, nbGroupsOfOtherMesh = 0; - for ( int i = 0; i < groups.length(); ++i ) + for ( CORBA::ULong i = 0; i < groups.length(); ++i ) { SMESH::SMESH_Mesh_var m = groups[i]->GetMesh(); - if ( myMesh_i != SMESH::DownCast( m )) + if ( !m->_is_nil() && myMesh_i != SMESH::DownCast( m )) groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i]; else groupsOfThisMesh[ nbGroups++ ] = groups[i]; if ( SMESH::DownCast( groups[i] )) - THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM); + THROW_SALOME_CORBA_EXCEPTION("expected a group but received a mesh", SALOME::BAD_PARAM); } groupsOfThisMesh->length( nbGroups ); groupsOfOtherMesh->length( nbGroupsOfOtherMesh ); @@ -7151,7 +7159,7 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim, // group of boundary elements SMESH_Group* smesh_group = 0; SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face; - if ( strlen(groupName) ) + if ( strlen( groupName )) { SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 ); group_var = mesh_i->CreateGroup( groupType, groupName ); @@ -7202,7 +7210,7 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim, else pyDump << mesh_var << ", "; if ( group_var->_is_nil() ) - pyDump << "_NoneGroup = "; // assignment to None is forbiden + pyDump << "_NoneGroup = "; // assignment to None is forbidden else pyDump << group_var << " = "; pyDump << this << ".MakeBoundaryElements( " @@ -7219,3 +7227,192 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim, SMESH_CATCH( SMESH::throwCorbaException ); return 0; } + +//================================================================================ +/*! + * \brief Create a polyline consisting of 1D mesh elements each lying on a 2D element of + * the initial mesh. Positions of new nodes are found by cutting the mesh by the + * plane passing through pairs of points specified by each PolySegment structure. + * If there are several paths connecting a pair of points, the shortest path is + * selected by the module. Position of the cutting plane is defined by the two + * points and an optional vector lying on the plane specified by a PolySegment. + * By default the vector is defined by Mesh module as following. A middle point + * of the two given points is computed. The middle point is projected to the mesh. + * The vector goes from the middle point to the projection point. In case of planar + * mesh, the vector is normal to the mesh. + * \param [inout] segments - PolySegment's defining positions of cutting planes. + * Return the used vector and position of the middle point. + * \param [in] groupName - optional name of a group where created mesh segments will + * be added. + */ +//================================================================================ + +void SMESH_MeshEditor_i::MakePolyLine(SMESH::ListOfPolySegments& theSegments, + const char* theGroupName) +{ + if ( theSegments.length() == 0 ) + THROW_SALOME_CORBA_EXCEPTION("No segments given", SALOME::BAD_PARAM ); + if ( myMesh->NbFaces() == 0 ) + THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM ); + + SMESH_TRY; + initData(/*deleteSearchers=*/false); + + SMESHDS_Group* groupDS = 0; + SMESHDS_Mesh* meshDS = getMeshDS(); + if ( myIsPreviewMode ) // copy faces to the tmp mesh + { + TPreviewMesh * tmpMesh = getPreviewMesh( SMDSAbs_Edge ); + SMDS_ElemIteratorPtr faceIt = getMeshDS()->elementsIterator( SMDSAbs_Face ); + while ( faceIt->more() ) + tmpMesh->Copy( faceIt->next() ); + meshDS = tmpMesh->GetMeshDS(); + } + else if ( theGroupName[0] ) // find/create a group of segments + { + // SMESH_Mesh::GroupIteratorPtr grpIt = myMesh->GetGroups(); + // while ( !groupDS && grpIt->more() ) + // { + // SMESH_Group* group = grpIt->next(); + // if ( group->GetGroupDS()->GetType() == SMDSAbs_Edge && + // strcmp( group->GetName(), theGroupName ) == 0 ) + // { + // groupDS = dynamic_cast< SMESHDS_Group* >( group->GetGroupDS() ); + // } + // } + if ( !groupDS ) + { + SMESH::SMESH_Group_var groupVar = myMesh_i->CreateGroup( SMESH::EDGE, theGroupName ); + + if ( SMESH_Group_i* groupImpl = SMESH::DownCast( groupVar )) + groupDS = dynamic_cast< SMESHDS_Group* >( groupImpl->GetGroupDS() ); + } + } + + // convert input polySegments + SMESH_MeshAlgos::TListOfPolySegments segments( theSegments.length() ); + for ( CORBA::ULong i = 0; i < theSegments.length(); ++i ) + { + SMESH::PolySegment& segIn = theSegments[ i ]; + SMESH_MeshAlgos::PolySegment& segOut = segments[ i ]; + segOut.myNode1[0] = meshDS->FindNode( segIn.node1ID1 ); + segOut.myNode2[0] = meshDS->FindNode( segIn.node1ID2 ); + segOut.myNode1[1] = meshDS->FindNode( segIn.node2ID1 ); + segOut.myNode2[1] = meshDS->FindNode( segIn.node2ID2 ); + segOut.myXYZ[0].SetCoord( segIn.xyz1.x, + segIn.xyz1.y, + segIn.xyz1.z); + segOut.myXYZ[1].SetCoord( segIn.xyz2.x, + segIn.xyz2.y, + segIn.xyz2.z); + segOut.myVector.SetCoord( segIn.vector.PS.x, + segIn.vector.PS.y, + segIn.vector.PS.z ); + } + + // get a static ElementSearcher + SMESH::SMESH_IDSource_var idSource = SMESH::SMESH_IDSource::_narrow( myMesh_i->_this() ); + theSearchersDeleter.Set( myMesh, getPartIOR( idSource, SMESH::FACE )); + if ( !theElementSearcher ) + theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() ); + + // compute + std::vector newEdges; + std::vector newNodes; + SMESH_MeshAlgos::MakePolyLine( meshDS, segments, newEdges, newNodes, + groupDS ? &groupDS->SMDSGroup() : 0, + theElementSearcher ); + + const_cast< SMESH_SequenceOfElemPtr& >( getEditor().GetLastCreatedElems() ). + swap( newEdges ); + const_cast< SMESH_SequenceOfElemPtr& >( getEditor().GetLastCreatedNodes() ). + assign( newNodes.begin(), newNodes.end() ); + + // return vectors + if ( myIsPreviewMode ) + { + for ( CORBA::ULong i = 0; i < theSegments.length(); ++i ) + { + SMESH::PolySegment& segOut = theSegments[ i ]; + SMESH_MeshAlgos::PolySegment& segIn = segments[ i ]; + segOut.vector.PS.x = segIn.myVector.X(); + segOut.vector.PS.y = segIn.myVector.Y(); + segOut.vector.PS.z = segIn.myVector.Z(); + } + } + else + { + TPythonDump() << "_segments = []"; + for ( CORBA::ULong i = 0; i < theSegments.length(); ++i ) + { + SMESH::PolySegment& segIn = theSegments[ i ]; + TPythonDump() << "_segments.append( SMESH.PolySegment( " + << segIn.node1ID1 << ", " + << segIn.node1ID2 << ", " + << segIn.node2ID1 << ", " + << segIn.node2ID2 << ", " + << "smeshBuilder.MakeDirStruct( " + << segIn.vector.PS.x << ", " + << segIn.vector.PS.y << ", " + << segIn.vector.PS.z << ")))"; + } + TPythonDump() << this << ".MakePolyLine( _segments, '" << theGroupName << "')"; + } + meshDS->Modified(); + SMESH_CATCH( SMESH::throwCorbaException ); + return; +} + +//================================================================================ +/*! + * \brief Create a slot of given width around given 1D elements lying on a triangle mesh. + * The slot is constructed by cutting faces by cylindrical surfaces made + * around each segment. Segments are expected to be created by MakePolyLine(). + * \return Edges located at the slot boundary + */ +//================================================================================ + +SMESH::ListOfEdges* SMESH_MeshEditor_i::MakeSlot(SMESH::SMESH_GroupBase_ptr theSegments, + CORBA::Double theWidth) +{ + if ( CORBA::is_nil( theSegments ) || + theSegments->GetType() != SMESH::EDGE ) + THROW_SALOME_CORBA_EXCEPTION("No segments given", SALOME::BAD_PARAM ); + if ( myMesh->NbFaces() == 0 ) + THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM ); + + SMESH::ListOfEdges_var resultEdges = new SMESH::ListOfEdges; + + SMESH_TRY; + initData(/*deleteSearchers=*/false); + + SMESHDS_Mesh* meshDS = getMeshDS(); + + // get standalone face groups to be updated + std::vector< SMDS_MeshGroup* > faceGroups; + const std::set& allGroups = meshDS->GetGroups(); + std::set::const_iterator grIt = allGroups.begin(); + for ( ; grIt != allGroups.end(); ++grIt ) + if ( const SMESHDS_Group* gr = dynamic_cast< const SMESHDS_Group* >( *grIt )) + if ( gr->GetType() == SMDSAbs_Face ) + faceGroups.push_back( & const_cast< SMESHDS_Group* >( gr )->SMDSGroup() ); + + std::vector< SMESH_MeshAlgos::Edge > edges = + SMESH_MeshAlgos::MakeSlot( SMESH_Mesh_i::GetElements( theSegments, SMESH::EDGE ), + theWidth, meshDS, faceGroups ); + + resultEdges->length( edges.size() ); + for ( size_t i = 0; i < edges.size(); ++i ) + { + resultEdges[ i ].node1 = edges[i]._node1->GetID(); + resultEdges[ i ].node2 = edges[i]._node2->GetID(); + resultEdges[ i ].medium = edges[i]._medium ? edges[i]._medium->GetID() : 0; + } + + meshDS->Modified(); + SMESH_CATCH( SMESH::throwCorbaException ); + + TSearchersDeleter::Delete(); // face searcher becomes invalid as some faces were removed + + return resultEdges._retn(); +}