1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_MeshEditor_i.cxx
23 // Author : Nicolas REJNERI
30 // A macro used in SMESH_TryCatch.hxx,
31 // it re-raises a CORBA SALOME exception thrown by SMESH_MeshEditor_i and caught by SMESH_CATCH
32 #define SMY_OWN_CATCH \
33 catch ( SALOME::SALOME_Exception & e ) { throw e; }
35 #include "SMESH_MeshEditor_i.hxx"
37 #include "SMDS_EdgePosition.hxx"
38 #include "SMDS_ElemIterator.hxx"
39 #include "SMDS_FacePosition.hxx"
40 #include "SMDS_IteratorOnIterators.hxx"
41 #include "SMDS_LinearEdge.hxx"
42 #include "SMDS_Mesh0DElement.hxx"
43 #include "SMDS_MeshFace.hxx"
44 #include "SMDS_MeshVolume.hxx"
45 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
46 #include "SMDS_SetIterator.hxx"
47 #include "SMDS_VolumeTool.hxx"
48 #include "SMESHDS_Group.hxx"
49 #include "SMESHDS_GroupOnGeom.hxx"
50 #include "SMESH_ControlsDef.hxx"
51 #include "SMESH_Filter_i.hxx"
52 #include "SMESH_Gen_i.hxx"
53 #include "SMESH_Group.hxx"
54 #include "SMESH_Group_i.hxx"
55 #include "SMESH_MeshAlgos.hxx"
56 #include "SMESH_MeshPartDS.hxx"
57 #include "SMESH_MesherHelper.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMeshEventListener.hxx"
60 #include "SMESH_subMesh_i.hxx"
62 #include <utilities.h>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <Utils_CorbaException.hxx>
65 #include <SALOMEDS_wrap.hxx>
66 #include <SALOME_GenericObj_i.hh>
67 #include <Basics_OCCTVersion.hxx>
69 #include <BRepAdaptor_Surface.hxx>
70 #include <BRep_Tool.hxx>
71 #include <TopExp_Explorer.hxx>
73 #include <TopoDS_Edge.hxx>
74 #include <TopoDS_Face.hxx>
79 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
83 #include <Standard_Failure.hxx>
86 #include <Standard_ErrorHandler.hxx>
92 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
94 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
97 using SMESH::TPythonDump;
100 namespace MeshEditor_I {
102 //=============================================================================
104 * \brief Mesh to apply modifications for preview purposes
106 //=============================================================================
108 struct TPreviewMesh: public SMESH_Mesh
110 SMDSAbs_ElementType myPreviewType; // type to show
112 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
113 _isShapeToMesh = (_id =_studyId = 0);
114 _myMeshDS = new SMESHDS_Mesh( _id, true );
115 myPreviewType = previewElements;
117 //!< Copy a set of elements
118 void Copy(const TIDSortedElemSet & theElements,
119 TIDSortedElemSet& theCopyElements,
120 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
121 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
123 // loop on theIDsOfElements
124 TIDSortedElemSet::const_iterator eIt = theElements.begin();
125 for ( ; eIt != theElements.end(); ++eIt )
127 const SMDS_MeshElement* anElem = *eIt;
128 if ( !anElem ) continue;
129 SMDSAbs_ElementType type = anElem->GetType();
130 if ( type == theAvoidType ||
131 ( theSelectType != SMDSAbs_All && type != theSelectType ))
133 const SMDS_MeshElement* anElemCopy;
134 if ( type == SMDSAbs_Node)
135 anElemCopy = Copy( cast2Node(anElem) );
137 anElemCopy = Copy( anElem );
139 theCopyElements.insert( theCopyElements.end(), anElemCopy );
143 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
145 // copy element nodes
146 int anElemNbNodes = anElem->NbNodes();
147 vector< int > anElemNodesID( anElemNbNodes ) ;
148 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
149 for ( int i = 0; itElemNodes->more(); i++)
151 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
153 anElemNodesID[i] = anElemNode->GetID();
156 // creates a corresponding element on copied nodes
157 SMDS_MeshElement* anElemCopy = 0;
158 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
160 const SMDS_VtkVolume* ph =
161 dynamic_cast<const SMDS_VtkVolume*> (anElem);
163 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
164 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
167 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
174 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
176 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
177 anElemNode->GetID());
181 GetMeshDS()->ClearMesh();
183 void Remove( SMDSAbs_ElementType type )
185 SMDS_ElemIteratorPtr eIt = GetMeshDS()->elementsIterator( type );
186 while ( eIt->more() )
187 GetMeshDS()->RemoveFreeElement( eIt->next(), /*sm=*/0, /*fromGroups=*/false );
189 };// struct TPreviewMesh
191 static SMESH_NodeSearcher * theNodeSearcher = 0;
192 static SMESH_ElementSearcher * theElementSearcher = 0;
194 //=============================================================================
196 * \brief Deleter of theNodeSearcher at any compute event occured
198 //=============================================================================
200 struct TSearchersDeleter : public SMESH_subMeshEventListener
203 string myMeshPartIOR;
205 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
206 "SMESH_MeshEditor_i::TSearchersDeleter"),
208 //!< Delete theNodeSearcher
211 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
212 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
214 typedef map < int, SMESH_subMesh * > TDependsOnMap;
215 //!< The meshod called by submesh: do my main job
216 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
217 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
219 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
221 Unset( sm->GetFather() );
224 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
225 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
227 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
234 myMeshPartIOR = meshPartIOR;
235 SMESH_subMesh* sm = mesh->GetSubMesh( mesh->GetShapeToMesh() );
236 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
237 while ( smIt->more() )
240 sm->SetEventListener( this, 0, sm );
244 //!< delete self from all submeshes
245 void Unset(SMESH_Mesh* mesh)
247 if ( SMESH_subMesh* sm = mesh->GetSubMeshContaining(1) ) {
248 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
249 while ( smIt->more() )
250 smIt->next()->DeleteEventListener( this );
255 } theSearchersDeleter;
257 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
259 TCollection_AsciiString typeStr;
260 switch ( theMirrorType ) {
261 case SMESH::SMESH_MeshEditor::POINT:
262 typeStr = "SMESH.SMESH_MeshEditor.POINT";
264 case SMESH::SMESH_MeshEditor::AXIS:
265 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
268 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
272 //================================================================================
274 * \brief function for conversion of long_array to TIDSortedElemSet
275 * \param IDs - array of IDs
276 * \param aMesh - mesh
277 * \param aMap - collection to fill
278 * \param aType - element type
280 //================================================================================
282 void arrayToSet(const SMESH::long_array & IDs,
283 const SMESHDS_Mesh* aMesh,
284 TIDSortedElemSet& aMap,
285 const SMDSAbs_ElementType aType = SMDSAbs_All,
286 SMDS_MeshElement::Filter* aFilter = NULL)
288 SMDS_MeshElement::NonNullFilter filter1;
289 SMDS_MeshElement::TypeFilter filter2( aType );
291 if ( aFilter == NULL )
292 aFilter = ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter*) &filter1 : (SMDS_MeshElement::Filter*) &filter2;
294 SMDS_MeshElement::Filter & filter = *aFilter;
296 if ( aType == SMDSAbs_Node )
297 for (int i=0; i<IDs.length(); i++) {
298 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
300 aMap.insert( aMap.end(), elem );
303 for (int i=0; i<IDs.length(); i++) {
304 const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
306 aMap.insert( aMap.end(), elem );
310 //================================================================================
312 * \brief Retrieve nodes from SMESH_IDSource
314 //================================================================================
316 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
317 const SMESHDS_Mesh* theMeshDS,
318 TIDSortedNodeSet& theNodeSet)
321 if ( CORBA::is_nil( theObject ) )
323 SMESH::array_of_ElementType_var types = theObject->GetTypes();
324 SMESH::long_array_var aElementsId = theObject->GetIDs();
325 if ( types->length() == 1 && types[0] == SMESH::NODE)
327 for(int i = 0; i < aElementsId->length(); i++)
328 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
329 theNodeSet.insert( theNodeSet.end(), n);
331 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
333 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
334 while ( nIt->more( ))
335 if( const SMDS_MeshElement * elem = nIt->next() )
336 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
340 for(int i = 0; i < aElementsId->length(); i++)
341 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
342 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
346 //================================================================================
348 * \brief Returns elements connected to the given elements
350 //================================================================================
352 void getElementsAround(const TIDSortedElemSet& theElements,
353 const SMESHDS_Mesh* theMeshDS,
354 TIDSortedElemSet& theElementsAround)
356 if ( theElements.empty() ) return;
358 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
359 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
361 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
362 return; // all the elements are in theElements
365 elemType = SMDSAbs_All;
367 vector<bool> isNodeChecked( theMeshDS->NbNodes(), false );
369 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
370 for ( ; elemIt != theElements.end(); ++elemIt )
372 const SMDS_MeshElement* e = *elemIt;
373 int i = e->NbCornerNodes();
376 const SMDS_MeshNode* n = e->GetNode( i );
377 if ( !isNodeChecked[ n->GetID() ])
379 isNodeChecked[ n->GetID() ] = true;
380 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
381 while ( invIt->more() )
383 const SMDS_MeshElement* elemAround = invIt->next();
384 if ( !theElements.count( elemAround ))
385 theElementsAround.insert( elemAround );
392 //================================================================================
394 * \brief Return a string used to detect change of mesh part on which theElementSearcher
395 * is going to be used
397 //================================================================================
399 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
401 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
402 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
403 // take into account passible group modification
404 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
405 partIOR += SMESH_Comment( type );
409 } // namespace MeshEditor_I
411 using namespace MeshEditor_I;
413 //=============================================================================
417 //=============================================================================
419 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
421 myMesh( &theMesh->GetImpl() ),
423 myIsPreviewMode ( isPreview ),
429 //================================================================================
433 //================================================================================
435 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
437 PortableServer::POA_var poa = SMESH_Gen_i::GetPOA();
438 PortableServer::ObjectId_var anObjectId = poa->servant_to_id(this);
439 poa->deactivate_object(anObjectId.in());
441 //deleteAuxIDSources();
442 delete myPreviewMesh; myPreviewMesh = 0;
443 delete myPreviewEditor; myPreviewEditor = 0;
446 //================================================================================
448 * \brief Returns the mesh
450 //================================================================================
452 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::GetMesh()
454 return myMesh_i->_this();
457 //================================================================================
459 * \brief Clear members
461 //================================================================================
463 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
465 if ( myIsPreviewMode ) {
466 if ( myPreviewMesh ) myPreviewMesh->RemoveAll();
469 if ( deleteSearchers )
470 TSearchersDeleter::Delete();
472 getEditor().GetError().reset();
473 getEditor().ClearLastCreated();
476 //================================================================================
478 * \brief Increment mesh modif time and optionally record that the performed
479 * modification may influence futher mesh re-compute.
480 * \param [in] isReComputeSafe - true if the modification does not influence
481 * futher mesh re-compute
483 //================================================================================
485 void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
487 myMesh->GetMeshDS()->Modified();
488 if ( !isReComputeSafe )
489 myMesh->SetIsModified( true );
492 //================================================================================
494 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
495 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
497 //================================================================================
499 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
501 if ( myIsPreviewMode && !myPreviewEditor ) {
502 if ( !myPreviewMesh ) getPreviewMesh();
503 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
505 return myIsPreviewMode ? *myPreviewEditor : myEditor;
508 //================================================================================
510 * \brief Initialize and return myPreviewMesh
511 * \param previewElements - type of elements to show in preview
513 * WARNING: call it once par a method!
515 //================================================================================
517 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
519 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
521 delete myPreviewEditor;
523 delete myPreviewMesh;
524 myPreviewMesh = new TPreviewMesh( previewElements );
526 myPreviewMesh->Clear();
527 return myPreviewMesh;
530 //================================================================================
532 * Return data of mesh edition preview
534 //================================================================================
536 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
537 throw (SALOME::SALOME_Exception)
540 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
542 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
544 list<int> aNodesConnectivity;
545 typedef map<int, int> TNodesMap;
548 SMESHDS_Mesh* aMeshDS;
549 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
551 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
552 aMeshDS = aMeshPartDS.get();
555 aMeshDS = getEditor().GetMeshDS();
557 myPreviewData = new SMESH::MeshPreviewStruct();
558 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
561 SMDSAbs_ElementType previewType = SMDSAbs_All;
563 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
564 previewType = aPreviewMesh->myPreviewType;
565 switch ( previewType ) {
566 case SMDSAbs_Edge : break;
567 case SMDSAbs_Face : break;
568 case SMDSAbs_Volume: break;
570 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
574 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
576 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
578 while ( itMeshElems->more() ) {
579 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
580 SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator();
581 while ( itElemNodes->more() ) {
582 const SMDS_MeshNode* aMeshNode = itElemNodes->next();
583 int aNodeID = aMeshNode->GetID();
584 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
585 if ( anIter == nodesMap.end() ) {
586 // filling the nodes coordinates
587 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
588 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
589 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
590 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
593 aNodesConnectivity.push_back(anIter->second);
596 // filling the elements types
597 SMDSAbs_ElementType aType = aMeshElem->GetType();
598 bool isPoly = aMeshElem->IsPoly();
599 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
600 myPreviewData->elementTypes[i].isPoly = isPoly;
601 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
604 myPreviewData->nodesXYZ.length( j );
606 // filling the elements connectivities
607 list<int>::iterator aConnIter = aNodesConnectivity.begin();
608 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
609 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
610 myPreviewData->elementConnectivities[i] = *aConnIter;
612 return myPreviewData._retn();
614 SMESH_CATCH( SMESH::throwCorbaException );
618 //================================================================================
620 * \brief Returns list of it's IDs of created nodes
621 * \retval SMESH::long_array* - list of node ID
623 //================================================================================
625 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
626 throw (SALOME::SALOME_Exception)
629 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
631 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
632 myLastCreatedNodes->length( aSeq.Length() );
633 for (int i = 1; i <= aSeq.Length(); i++)
634 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
636 return myLastCreatedNodes._retn();
637 SMESH_CATCH( SMESH::throwCorbaException );
641 //================================================================================
643 * \brief Returns list of it's IDs of created elements
644 * \retval SMESH::long_array* - list of elements' ID
646 //================================================================================
648 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
649 throw (SALOME::SALOME_Exception)
652 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
654 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
655 myLastCreatedElems->length( aSeq.Length() );
656 for ( int i = 1; i <= aSeq.Length(); i++ )
657 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
659 return myLastCreatedElems._retn();
660 SMESH_CATCH( SMESH::throwCorbaException );
664 //=======================================================================
665 //function : ClearLastCreated
666 //purpose : Clears sequences of last created elements and nodes
667 //=======================================================================
669 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
672 getEditor().ClearLastCreated();
673 SMESH_CATCH( SMESH::throwCorbaException );
676 //=======================================================================
678 * Returns description of an error/warning occured during the last operation
679 * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
681 //=======================================================================
683 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
684 throw (SALOME::SALOME_Exception)
687 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
688 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
689 if ( errIn && !errIn->IsOK() )
691 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
692 errOut->comment = errIn->myComment.c_str();
693 errOut->subShapeID = -1;
694 errOut->hasBadMesh = !errIn->myBadElements.empty();
699 errOut->subShapeID = -1;
700 errOut->hasBadMesh = false;
703 return errOut._retn();
704 SMESH_CATCH( SMESH::throwCorbaException );
708 //=======================================================================
709 //function : MakeIDSource
710 //purpose : Wrap a sequence of ids in a SMESH_IDSource.
711 // Call UnRegister() as you fininsh using it!!
712 //=======================================================================
714 struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource,
715 public virtual SALOME::GenericObj_i
717 SMESH::long_array _ids;
718 SMESH::ElementType _type;
719 SMESH::SMESH_Mesh_ptr _mesh;
720 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
721 SMESH::long_array* GetMeshInfo() { return 0; }
722 SMESH::long_array* GetNbElementsByType()
724 SMESH::long_array_var aRes = new SMESH::long_array();
725 aRes->length(SMESH::NB_ELEMENT_TYPES);
726 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
727 aRes[ i ] = ( i == _type ) ? _ids.length() : 0;
730 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
731 bool IsMeshInfoCorrect() { return true; }
732 SMESH::array_of_ElementType* GetTypes()
734 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
735 if ( _ids.length() > 0 ) {
739 return types._retn();
741 SALOMEDS::TMPFile* GetVtkUgStream()
743 SALOMEDS::TMPFile_var SeqFile;
744 return SeqFile._retn();
748 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
749 SMESH::ElementType type)
751 _IDSource* idSrc = new _IDSource;
752 idSrc->_mesh = myMesh_i->_this();
755 if ( type == SMESH::ALL && ids.length() > 0 )
756 idSrc->_type = myMesh_i->GetElementType( ids[0], true );
758 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
760 return anIDSourceVar._retn();
763 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
765 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
768 CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource,
771 if ( _IDSource* tmpIdSource = SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource ))
773 nbIds = (int) tmpIdSource->_ids.length();
774 return & tmpIdSource->_ids[0];
780 // void SMESH_MeshEditor_i::deleteAuxIDSources()
782 // std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
783 // for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
785 // myAuxIDSources.clear();
788 //=============================================================================
792 //=============================================================================
795 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
796 throw (SALOME::SALOME_Exception)
803 for (int i = 0; i < IDsOfElements.length(); i++)
804 IdList.push_back( IDsOfElements[i] );
806 // Update Python script
807 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
810 bool ret = getEditor().Remove( IdList, false );
812 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
815 SMESH_CATCH( SMESH::throwCorbaException );
819 //=============================================================================
823 //=============================================================================
825 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
826 throw (SALOME::SALOME_Exception)
832 for (int i = 0; i < IDsOfNodes.length(); i++)
833 IdList.push_back( IDsOfNodes[i] );
835 // Update Python script
836 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
838 bool ret = getEditor().Remove( IdList, true );
840 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
843 SMESH_CATCH( SMESH::throwCorbaException );
847 //=============================================================================
851 //=============================================================================
853 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
854 throw (SALOME::SALOME_Exception)
859 // Update Python script
860 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
862 // Create filter to find all orphan nodes
863 SMESH::Controls::Filter::TIdSequence seq;
864 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
865 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
867 // remove orphan nodes (if there are any)
869 for ( int i = 0; i < seq.size(); i++ )
870 IdList.push_back( seq[i] );
872 int nbNodesBefore = myMesh->NbNodes();
873 getEditor().Remove( IdList, true );
874 int nbNodesAfter = myMesh->NbNodes();
876 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
877 return nbNodesBefore - nbNodesAfter;
879 SMESH_CATCH( SMESH::throwCorbaException );
883 //=============================================================================
887 //=============================================================================
889 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
890 throw (SALOME::SALOME_Exception)
895 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
897 // Update Python script
898 TPythonDump() << "nodeID = " << this << ".AddNode( "
899 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
901 declareMeshModified( /*isReComputeSafe=*/false );
904 SMESH_CATCH( SMESH::throwCorbaException );
908 //=============================================================================
910 * Create 0D element on the given node.
912 //=============================================================================
914 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
915 throw (SALOME::SALOME_Exception)
920 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
921 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
923 // Update Python script
924 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
926 declareMeshModified( /*isReComputeSafe=*/false );
928 return elem ? elem->GetID() : 0;
930 SMESH_CATCH( SMESH::throwCorbaException );
934 //=============================================================================
936 * Create a ball element on the given node.
938 //=============================================================================
940 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
941 throw (SALOME::SALOME_Exception)
946 if ( diameter < std::numeric_limits<double>::min() )
947 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
949 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
950 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
952 // Update Python script
953 TPythonDump() << "ballElem = "
954 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
956 declareMeshModified( /*isReComputeSafe=*/false );
957 return elem ? elem->GetID() : 0;
959 SMESH_CATCH( SMESH::throwCorbaException );
963 //=============================================================================
965 * Create an edge, either linear and quadratic (this is determed
966 * by number of given nodes, two or three)
968 //=============================================================================
970 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
971 throw (SALOME::SALOME_Exception)
976 int NbNodes = IDsOfNodes.length();
977 SMDS_MeshElement* elem = 0;
980 CORBA::Long index1 = IDsOfNodes[0];
981 CORBA::Long index2 = IDsOfNodes[1];
982 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
983 getMeshDS()->FindNode(index2));
985 // Update Python script
986 TPythonDump() << "edge = " << this << ".AddEdge([ "
987 << index1 << ", " << index2 <<" ])";
990 CORBA::Long n1 = IDsOfNodes[0];
991 CORBA::Long n2 = IDsOfNodes[1];
992 CORBA::Long n12 = IDsOfNodes[2];
993 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
994 getMeshDS()->FindNode(n2),
995 getMeshDS()->FindNode(n12));
996 // Update Python script
997 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
998 <<n1<<", "<<n2<<", "<<n12<<" ])";
1001 declareMeshModified( /*isReComputeSafe=*/false );
1002 return elem ? elem->GetID() : 0;
1004 SMESH_CATCH( SMESH::throwCorbaException );
1008 //=============================================================================
1012 //=============================================================================
1014 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1015 throw (SALOME::SALOME_Exception)
1020 int NbNodes = IDsOfNodes.length();
1026 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1027 for (int i = 0; i < NbNodes; i++)
1028 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1030 SMDS_MeshElement* elem = 0;
1032 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1033 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1034 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1035 nodes[4], nodes[5]); break;
1036 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1037 nodes[4], nodes[5], nodes[6]); break;
1038 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1039 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1040 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1041 nodes[4], nodes[5], nodes[6], nodes[7],
1043 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1046 // Update Python script
1047 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1049 declareMeshModified( /*isReComputeSafe=*/false );
1051 return elem ? elem->GetID() : 0;
1053 SMESH_CATCH( SMESH::throwCorbaException );
1057 //=============================================================================
1061 //=============================================================================
1062 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1063 throw (SALOME::SALOME_Exception)
1068 int NbNodes = IDsOfNodes.length();
1069 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1070 for (int i = 0; i < NbNodes; i++)
1071 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1073 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1075 // Update Python script
1076 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1078 declareMeshModified( /*isReComputeSafe=*/false );
1079 return elem ? elem->GetID() : 0;
1081 SMESH_CATCH( SMESH::throwCorbaException );
1085 //=============================================================================
1087 * Create volume, either linear and quadratic (this is determed
1088 * by number of given nodes)
1090 //=============================================================================
1092 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1093 throw (SALOME::SALOME_Exception)
1098 int NbNodes = IDsOfNodes.length();
1099 vector< const SMDS_MeshNode*> n(NbNodes);
1100 for(int i=0;i<NbNodes;i++)
1101 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1103 SMDS_MeshElement* elem = 0;
1106 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1107 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1108 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1109 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1110 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1111 n[6],n[7],n[8],n[9]);
1113 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1114 n[6],n[7],n[8],n[9],n[10],n[11]);
1116 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1117 n[7],n[8],n[9],n[10],n[11],n[12]);
1119 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1120 n[9],n[10],n[11],n[12],n[13],n[14]);
1122 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1123 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1124 n[15],n[16],n[17],n[18],n[19]);
1126 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1127 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1128 n[15],n[16],n[17],n[18],n[19],
1129 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1133 // Update Python script
1134 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1136 declareMeshModified( /*isReComputeSafe=*/false );
1137 return elem ? elem->GetID() : 0;
1139 SMESH_CATCH( SMESH::throwCorbaException );
1143 //=============================================================================
1145 * AddPolyhedralVolume
1147 //=============================================================================
1148 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1149 const SMESH::long_array & Quantities)
1150 throw (SALOME::SALOME_Exception)
1155 int NbNodes = IDsOfNodes.length();
1156 std::vector<const SMDS_MeshNode*> n (NbNodes);
1157 for (int i = 0; i < NbNodes; i++)
1159 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1160 if (!aNode) return 0;
1164 int NbFaces = Quantities.length();
1165 std::vector<int> q (NbFaces);
1166 for (int j = 0; j < NbFaces; j++)
1167 q[j] = Quantities[j];
1169 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1171 // Update Python script
1172 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1173 << IDsOfNodes << ", " << Quantities << " )";
1175 declareMeshModified( /*isReComputeSafe=*/false );
1176 return elem ? elem->GetID() : 0;
1178 SMESH_CATCH( SMESH::throwCorbaException );
1182 //=============================================================================
1184 * AddPolyhedralVolumeByFaces
1186 //=============================================================================
1188 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1189 throw (SALOME::SALOME_Exception)
1194 int NbFaces = IdsOfFaces.length();
1195 std::vector<const SMDS_MeshNode*> poly_nodes;
1196 std::vector<int> quantities (NbFaces);
1198 for (int i = 0; i < NbFaces; i++) {
1199 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1200 quantities[i] = aFace->NbNodes();
1202 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1203 while (It->more()) {
1204 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1208 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1210 // Update Python script
1211 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1212 << IdsOfFaces << " )";
1214 declareMeshModified( /*isReComputeSafe=*/false );
1215 return elem ? elem->GetID() : 0;
1217 SMESH_CATCH( SMESH::throwCorbaException );
1221 //=============================================================================
1223 // \brief Create 0D elements on all nodes of the given object except those
1224 // nodes on which a 0D element already exists.
1225 // \param theObject object on whose nodes 0D elements will be created.
1226 // \param theGroupName optional name of a group to add 0D elements created
1227 // and/or found on nodes of \a theObject.
1228 // \return an object (a new group or a temporary SMESH_IDSource) holding
1229 // ids of new and/or found 0D elements.
1231 //=============================================================================
1233 SMESH::SMESH_IDSource_ptr
1234 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1235 const char* theGroupName)
1236 throw (SALOME::SALOME_Exception)
1241 SMESH::SMESH_IDSource_var result;
1244 TIDSortedElemSet elements, elems0D;
1245 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1246 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1248 SMESH::long_array_var newElems = new SMESH::long_array;
1249 newElems->length( elems0D.size() );
1250 TIDSortedElemSet::iterator eIt = elems0D.begin();
1251 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1252 newElems[ i ] = (*eIt)->GetID();
1254 SMESH::SMESH_GroupBase_var groupToFill;
1255 if ( theGroupName && strlen( theGroupName ))
1257 // Get existing group named theGroupName
1258 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1259 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1260 SMESH::SMESH_GroupBase_var group = groups[i];
1261 if ( !group->_is_nil() ) {
1262 CORBA::String_var name = group->GetName();
1263 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1264 groupToFill = group;
1269 if ( groupToFill->_is_nil() )
1270 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1271 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1272 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1275 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1277 group_i->Add( newElems );
1278 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1279 pyDump << groupToFill;
1283 result = MakeIDSource( newElems, SMESH::ELEM0D );
1284 pyDump << "elem0DIDs";
1287 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1288 << theObject << ", '" << theGroupName << "' )";
1290 return result._retn();
1292 SMESH_CATCH( SMESH::throwCorbaException );
1296 //=============================================================================
1298 * \brief Bind a node to a vertex
1299 * \param NodeID - node ID
1300 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1301 * \retval boolean - false if NodeID or VertexID is invalid
1303 //=============================================================================
1305 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1306 throw (SALOME::SALOME_Exception)
1310 SMESHDS_Mesh * mesh = getMeshDS();
1311 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1313 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1315 if ( mesh->MaxShapeIndex() < VertexID )
1316 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1318 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1319 if ( shape.ShapeType() != TopAbs_VERTEX )
1320 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1322 mesh->SetNodeOnVertex( node, VertexID );
1324 myMesh->SetIsModified( true );
1326 SMESH_CATCH( SMESH::throwCorbaException );
1329 //=============================================================================
1331 * \brief Store node position on an edge
1332 * \param NodeID - node ID
1333 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1334 * \param paramOnEdge - parameter on edge where the node is located
1335 * \retval boolean - false if any parameter is invalid
1337 //=============================================================================
1339 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1340 CORBA::Double paramOnEdge)
1341 throw (SALOME::SALOME_Exception)
1345 SMESHDS_Mesh * mesh = getMeshDS();
1346 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1348 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1350 if ( mesh->MaxShapeIndex() < EdgeID )
1351 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1353 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1354 if ( shape.ShapeType() != TopAbs_EDGE )
1355 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1358 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1359 if ( paramOnEdge < f || paramOnEdge > l )
1360 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1362 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1364 myMesh->SetIsModified( true );
1366 SMESH_CATCH( SMESH::throwCorbaException );
1369 //=============================================================================
1371 * \brief Store node position on a face
1372 * \param NodeID - node ID
1373 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1374 * \param u - U parameter on face where the node is located
1375 * \param v - V parameter on face where the node is located
1376 * \retval boolean - false if any parameter is invalid
1378 //=============================================================================
1380 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1381 CORBA::Double u, CORBA::Double v)
1382 throw (SALOME::SALOME_Exception)
1385 SMESHDS_Mesh * mesh = getMeshDS();
1386 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1388 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1390 if ( mesh->MaxShapeIndex() < FaceID )
1391 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1393 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1394 if ( shape.ShapeType() != TopAbs_FACE )
1395 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1397 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1398 bool isOut = ( u < surf.FirstUParameter() ||
1399 u > surf.LastUParameter() ||
1400 v < surf.FirstVParameter() ||
1401 v > surf.LastVParameter() );
1405 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1406 << " u( " << surf.FirstUParameter()
1407 << "," << surf.LastUParameter()
1408 << ") v( " << surf.FirstVParameter()
1409 << "," << surf.LastVParameter() << ")" );
1411 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1414 mesh->SetNodeOnFace( node, FaceID, u, v );
1415 myMesh->SetIsModified( true );
1417 SMESH_CATCH( SMESH::throwCorbaException );
1420 //=============================================================================
1422 * \brief Bind a node to a solid
1423 * \param NodeID - node ID
1424 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1425 * \retval boolean - false if NodeID or SolidID is invalid
1427 //=============================================================================
1429 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1430 throw (SALOME::SALOME_Exception)
1433 SMESHDS_Mesh * mesh = getMeshDS();
1434 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1436 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1438 if ( mesh->MaxShapeIndex() < SolidID )
1439 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1441 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1442 if ( shape.ShapeType() != TopAbs_SOLID &&
1443 shape.ShapeType() != TopAbs_SHELL)
1444 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1446 mesh->SetNodeInVolume( node, SolidID );
1448 SMESH_CATCH( SMESH::throwCorbaException );
1451 //=============================================================================
1453 * \brief Bind an element to a shape
1454 * \param ElementID - element ID
1455 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1457 //=============================================================================
1459 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1460 CORBA::Long ShapeID)
1461 throw (SALOME::SALOME_Exception)
1464 SMESHDS_Mesh * mesh = getMeshDS();
1465 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1467 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1469 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1470 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1472 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1473 if ( shape.ShapeType() != TopAbs_EDGE &&
1474 shape.ShapeType() != TopAbs_FACE &&
1475 shape.ShapeType() != TopAbs_SOLID &&
1476 shape.ShapeType() != TopAbs_SHELL )
1477 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1479 mesh->SetMeshElementOnShape( elem, ShapeID );
1481 myMesh->SetIsModified( true );
1483 SMESH_CATCH( SMESH::throwCorbaException );
1486 //=============================================================================
1490 //=============================================================================
1492 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1493 CORBA::Long NodeID2)
1494 throw (SALOME::SALOME_Exception)
1499 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1500 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1504 // Update Python script
1505 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1506 << NodeID1 << ", " << NodeID2 << " )";
1508 int ret = getEditor().InverseDiag ( n1, n2 );
1510 declareMeshModified( /*isReComputeSafe=*/false );
1513 SMESH_CATCH( SMESH::throwCorbaException );
1517 //=============================================================================
1521 //=============================================================================
1523 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1524 CORBA::Long NodeID2)
1525 throw (SALOME::SALOME_Exception)
1530 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1531 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1535 // Update Python script
1536 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1537 << NodeID1 << ", " << NodeID2 << " )";
1540 bool stat = getEditor().DeleteDiag ( n1, n2 );
1542 declareMeshModified( /*isReComputeSafe=*/!stat );
1546 SMESH_CATCH( SMESH::throwCorbaException );
1550 //=============================================================================
1554 //=============================================================================
1556 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1557 throw (SALOME::SALOME_Exception)
1562 for (int i = 0; i < IDsOfElements.length(); i++)
1564 CORBA::Long index = IDsOfElements[i];
1565 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1567 getEditor().Reorient( elem );
1569 // Update Python script
1570 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1572 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1575 SMESH_CATCH( SMESH::throwCorbaException );
1579 //=============================================================================
1583 //=============================================================================
1585 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1586 throw (SALOME::SALOME_Exception)
1591 TPythonDump aTPythonDump; // suppress dump in Reorient()
1593 prepareIdSource( theObject );
1595 SMESH::long_array_var anElementsId = theObject->GetIDs();
1596 CORBA::Boolean isDone = Reorient(anElementsId);
1598 // Update Python script
1599 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1601 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1604 SMESH_CATCH( SMESH::throwCorbaException );
1608 //=======================================================================
1609 //function : Reorient2D
1610 //purpose : Reorient faces contained in \a the2Dgroup.
1611 // the2Dgroup - the mesh or its part to reorient
1612 // theDirection - desired direction of normal of \a theFace
1613 // theFace - ID of face whose orientation is checked.
1614 // It can be < 1 then \a thePoint is used to find a face.
1615 // thePoint - is used to find a face if \a theFace < 1.
1616 // return number of reoriented elements.
1617 //=======================================================================
1619 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1620 const SMESH::DirStruct& theDirection,
1621 CORBA::Long theFace,
1622 const SMESH::PointStruct& thePoint)
1623 throw (SALOME::SALOME_Exception)
1626 initData(/*deleteSearchers=*/false);
1628 TIDSortedElemSet elements;
1629 IDSource_Error error;
1630 idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1631 if ( error == IDSource_EMPTY )
1633 if ( error == IDSource_INVALID )
1634 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1637 const SMDS_MeshElement* face = 0;
1640 face = getMeshDS()->FindElement( theFace );
1642 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1643 if ( face->GetType() != SMDSAbs_Face )
1644 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1648 // create theElementSearcher if needed
1649 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1650 if ( !theElementSearcher )
1652 if ( elements.empty() ) // search in the whole mesh
1654 if ( myMesh->NbFaces() == 0 )
1655 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1657 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1661 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1662 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1664 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1668 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1669 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1672 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1673 if ( !elements.empty() && !elements.count( face ))
1674 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1677 const SMESH::PointStruct * P = &theDirection.PS;
1678 gp_Vec dirVec( P->x, P->y, P->z );
1679 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1680 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1682 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1685 declareMeshModified( /*isReComputeSafe=*/false );
1687 TPythonDump() << this << ".Reorient2D( "
1688 << the2Dgroup << ", "
1689 << theDirection << ", "
1691 << thePoint << " )";
1695 SMESH_CATCH( SMESH::throwCorbaException );
1699 //=======================================================================
1700 //function : Reorient2DBy3D
1701 //purpose : Reorient faces basing on orientation of adjacent volumes.
1702 //=======================================================================
1704 CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& faceGroups,
1705 SMESH::SMESH_IDSource_ptr volumeGroup,
1706 CORBA::Boolean outsideNormal)
1707 throw (SALOME::SALOME_Exception)
1712 TIDSortedElemSet volumes;
1713 IDSource_Error volsError;
1714 idSourceToSet( volumeGroup, getMeshDS(), volumes, SMDSAbs_Volume, /*emptyIfMesh=*/1, &volsError);
1717 for ( size_t i = 0; i < faceGroups.length(); ++i )
1719 SMESH::SMESH_IDSource_ptr faceGrp = faceGroups[i].in();
1721 TIDSortedElemSet faces;
1722 IDSource_Error error;
1723 idSourceToSet( faceGrp, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1724 if ( error == IDSource_INVALID && faceGroups.length() == 1 )
1725 THROW_SALOME_CORBA_EXCEPTION("No faces in a given object", SALOME::BAD_PARAM);
1726 if ( error == IDSource_OK && volsError != IDSource_OK )
1727 THROW_SALOME_CORBA_EXCEPTION("No volumes in a given object", SALOME::BAD_PARAM);
1729 nbReori += getEditor().Reorient2DBy3D( faces, volumes, outsideNormal );
1731 if ( error != IDSource_EMPTY && faces.empty() ) // all faces in the mesh treated
1736 declareMeshModified( /*isReComputeSafe=*/false );
1738 TPythonDump() << this << ".Reorient2DBy3D( "
1739 << faceGroups << ", "
1740 << volumeGroup << ", "
1741 << outsideNormal << " )";
1745 SMESH_CATCH( SMESH::throwCorbaException );
1749 //=============================================================================
1751 * \brief Fuse neighbour triangles into quadrangles.
1753 //=============================================================================
1755 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1756 SMESH::NumericalFunctor_ptr Criterion,
1757 CORBA::Double MaxAngle)
1758 throw (SALOME::SALOME_Exception)
1763 SMESHDS_Mesh* aMesh = getMeshDS();
1764 TIDSortedElemSet faces,copyFaces;
1765 SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE);
1766 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter);
1767 TIDSortedElemSet* workElements = & faces;
1769 if ( myIsPreviewMode ) {
1770 SMDSAbs_ElementType select = SMDSAbs_Face;
1771 getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select );
1772 workElements = & copyFaces;
1775 SMESH::NumericalFunctor_i* aNumericalFunctor =
1776 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1777 SMESH::Controls::NumericalFunctorPtr aCrit;
1778 if ( !aNumericalFunctor )
1779 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1781 aCrit = aNumericalFunctor->GetNumericalFunctor();
1783 if ( !myIsPreviewMode ) {
1784 // Update Python script
1785 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1786 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1789 bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle );
1791 declareMeshModified( /*isReComputeSafe=*/!stat );
1794 SMESH_CATCH( SMESH::throwCorbaException );
1798 //=============================================================================
1800 * \brief Fuse neighbour triangles into quadrangles.
1802 //=============================================================================
1804 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1805 SMESH::NumericalFunctor_ptr Criterion,
1806 CORBA::Double MaxAngle)
1807 throw (SALOME::SALOME_Exception)
1812 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1814 prepareIdSource( theObject );
1815 SMESH::long_array_var anElementsId = theObject->GetIDs();
1816 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1818 if ( !myIsPreviewMode ) {
1819 SMESH::NumericalFunctor_i* aNumericalFunctor =
1820 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1822 // Update Python script
1823 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1824 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1829 SMESH_CATCH( SMESH::throwCorbaException );
1833 //=============================================================================
1835 * \brief Split quadrangles into triangles.
1837 //=============================================================================
1839 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1840 SMESH::NumericalFunctor_ptr Criterion)
1841 throw (SALOME::SALOME_Exception)
1846 SMESHDS_Mesh* aMesh = getMeshDS();
1847 TIDSortedElemSet faces;
1848 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1850 SMESH::NumericalFunctor_i* aNumericalFunctor =
1851 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1852 SMESH::Controls::NumericalFunctorPtr aCrit;
1853 if ( !aNumericalFunctor )
1854 aCrit.reset( new SMESH::Controls::AspectRatio() );
1856 aCrit = aNumericalFunctor->GetNumericalFunctor();
1859 // Update Python script
1860 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1862 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1864 declareMeshModified( /*isReComputeSafe=*/false );
1867 SMESH_CATCH( SMESH::throwCorbaException );
1871 //=============================================================================
1873 * \brief Split quadrangles into triangles.
1875 //=============================================================================
1877 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1878 SMESH::NumericalFunctor_ptr Criterion)
1879 throw (SALOME::SALOME_Exception)
1884 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1886 prepareIdSource( theObject );
1887 SMESH::long_array_var anElementsId = theObject->GetIDs();
1888 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1890 SMESH::NumericalFunctor_i* aNumericalFunctor =
1891 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1893 // Update Python script
1894 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1896 declareMeshModified( /*isReComputeSafe=*/false );
1899 SMESH_CATCH( SMESH::throwCorbaException );
1903 //================================================================================
1905 * \brief Split each of quadrangles into 4 triangles.
1906 * \param [in] theObject - theQuads Container of quadrangles to split.
1908 //================================================================================
1910 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1911 throw (SALOME::SALOME_Exception)
1916 TIDSortedElemSet faces;
1917 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1919 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1921 getEditor().QuadTo4Tri( faces );
1922 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1924 SMESH_CATCH( SMESH::throwCorbaException );
1927 //=============================================================================
1929 * \brief Split quadrangles into triangles.
1931 //=============================================================================
1933 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1934 CORBA::Boolean Diag13)
1935 throw (SALOME::SALOME_Exception)
1940 SMESHDS_Mesh* aMesh = getMeshDS();
1941 TIDSortedElemSet faces;
1942 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1944 // Update Python script
1945 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1946 << IDsOfElements << ", " << Diag13 << " )";
1948 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1950 declareMeshModified( /*isReComputeSafe=*/ !stat );
1953 SMESH_CATCH( SMESH::throwCorbaException );
1957 //=============================================================================
1959 * \brief Split quadrangles into triangles.
1961 //=============================================================================
1963 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1964 CORBA::Boolean Diag13)
1965 throw (SALOME::SALOME_Exception)
1970 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1972 prepareIdSource( theObject );
1973 SMESH::long_array_var anElementsId = theObject->GetIDs();
1974 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1976 // Update Python script
1977 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1978 << theObject << ", " << Diag13 << " )";
1980 declareMeshModified( /*isReComputeSafe=*/!isDone );
1983 SMESH_CATCH( SMESH::throwCorbaException );
1988 //=============================================================================
1990 * Find better splitting of the given quadrangle.
1991 * \param IDOfQuad ID of the quadrangle to be splitted.
1992 * \param Criterion A criterion to choose a diagonal for splitting.
1993 * \return 1 if 1-3 diagonal is better, 2 if 2-4
1994 * diagonal is better, 0 if error occurs.
1996 //=============================================================================
1998 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1999 SMESH::NumericalFunctor_ptr Criterion)
2000 throw (SALOME::SALOME_Exception)
2005 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
2006 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
2008 SMESH::NumericalFunctor_i* aNumericalFunctor =
2009 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
2010 SMESH::Controls::NumericalFunctorPtr aCrit;
2011 if (aNumericalFunctor)
2012 aCrit = aNumericalFunctor->GetNumericalFunctor();
2014 aCrit.reset(new SMESH::Controls::AspectRatio());
2016 int id = getEditor().BestSplit(quad, aCrit);
2017 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
2021 SMESH_CATCH( SMESH::throwCorbaException );
2025 //================================================================================
2027 * \brief Split volumic elements into tetrahedrons
2029 //================================================================================
2031 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
2032 CORBA::Short methodFlags)
2033 throw (SALOME::SALOME_Exception)
2038 ::SMESH_MeshEditor::TFacetOfElem elemSet;
2039 const int noneFacet = -1;
2040 SMDS_ElemIteratorPtr volIt = myMesh_i->GetElements( elems, SMESH::VOLUME );
2041 while( volIt->more() )
2042 elemSet.insert( elemSet.end(), make_pair( volIt->next(), noneFacet ));
2044 getEditor().SplitVolumes( elemSet, int( methodFlags ));
2045 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2047 TPythonDump() << this << ".SplitVolumesIntoTetra( "
2048 << elems << ", " << methodFlags << " )";
2050 SMESH_CATCH( SMESH::throwCorbaException );
2053 //================================================================================
2055 * \brief Split hexahedra into triangular prisms
2056 * \param elems - elements to split
2057 * \param facetToSplitNormal - normal used to find a facet of hexahedron
2058 * to split into triangles
2059 * \param methodFlags - flags passing splitting method:
2060 * 1 - split the hexahedron into 2 prisms
2061 * 2 - split the hexahedron into 4 prisms
2063 //================================================================================
2065 void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms (SMESH::SMESH_IDSource_ptr elems,
2066 const SMESH::PointStruct & startHexPoint,
2067 const SMESH::DirStruct& facetToSplitNormal,
2068 CORBA::Short methodFlags,
2069 CORBA::Boolean allDomains)
2070 throw (SALOME::SALOME_Exception)
2074 prepareIdSource( elems );
2076 gp_Ax1 facetNorm( gp_Pnt( startHexPoint.x,
2079 gp_Dir( facetToSplitNormal.PS.x,
2080 facetToSplitNormal.PS.y,
2081 facetToSplitNormal.PS.z ));
2082 TIDSortedElemSet elemSet;
2083 SMESH::long_array_var anElementsId = elems->GetIDs();
2084 SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA );
2085 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter );
2087 ::SMESH_MeshEditor::TFacetOfElem elemFacets;
2088 while ( !elemSet.empty() )
2090 getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets );
2094 ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin();
2095 for ( ; ef != elemFacets.end(); ++ef )
2096 elemSet.erase( ef->first );
2099 if ( methodFlags == 2 )
2100 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS );
2102 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS );
2104 getEditor().SplitVolumes( elemFacets, int( methodFlags ));
2105 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2107 TPythonDump() << this << ".SplitHexahedraIntoPrisms( "
2109 << startHexPoint << ", "
2110 << facetToSplitNormal<< ", "
2111 << methodFlags<< ", "
2112 << allDomains << " )";
2114 SMESH_CATCH( SMESH::throwCorbaException );
2117 //=======================================================================
2120 //=======================================================================
2123 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2124 const SMESH::long_array & IDsOfFixedNodes,
2125 CORBA::Long MaxNbOfIterations,
2126 CORBA::Double MaxAspectRatio,
2127 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2128 throw (SALOME::SALOME_Exception)
2130 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2131 MaxAspectRatio, Method, false );
2135 //=======================================================================
2136 //function : SmoothParametric
2138 //=======================================================================
2141 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2142 const SMESH::long_array & IDsOfFixedNodes,
2143 CORBA::Long MaxNbOfIterations,
2144 CORBA::Double MaxAspectRatio,
2145 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2146 throw (SALOME::SALOME_Exception)
2148 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2149 MaxAspectRatio, Method, true );
2153 //=======================================================================
2154 //function : SmoothObject
2156 //=======================================================================
2159 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2160 const SMESH::long_array & IDsOfFixedNodes,
2161 CORBA::Long MaxNbOfIterations,
2162 CORBA::Double MaxAspectRatio,
2163 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2164 throw (SALOME::SALOME_Exception)
2166 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2167 MaxAspectRatio, Method, false);
2171 //=======================================================================
2172 //function : SmoothParametricObject
2174 //=======================================================================
2177 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2178 const SMESH::long_array & IDsOfFixedNodes,
2179 CORBA::Long MaxNbOfIterations,
2180 CORBA::Double MaxAspectRatio,
2181 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2182 throw (SALOME::SALOME_Exception)
2184 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2185 MaxAspectRatio, Method, true);
2189 //=============================================================================
2193 //=============================================================================
2196 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2197 const SMESH::long_array & IDsOfFixedNodes,
2198 CORBA::Long MaxNbOfIterations,
2199 CORBA::Double MaxAspectRatio,
2200 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2202 throw (SALOME::SALOME_Exception)
2207 SMESHDS_Mesh* aMesh = getMeshDS();
2209 TIDSortedElemSet elements;
2210 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2212 set<const SMDS_MeshNode*> fixedNodes;
2213 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
2214 CORBA::Long index = IDsOfFixedNodes[i];
2215 const SMDS_MeshNode * node = aMesh->FindNode(index);
2217 fixedNodes.insert( node );
2219 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2220 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2221 method = ::SMESH_MeshEditor::CENTROIDAL;
2223 getEditor().Smooth(elements, fixedNodes, method,
2224 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2226 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2228 // Update Python script
2229 TPythonDump() << "isDone = " << this << "."
2230 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2231 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2232 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2233 << "SMESH.SMESH_MeshEditor."
2234 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2235 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2239 SMESH_CATCH( SMESH::throwCorbaException );
2243 //=============================================================================
2247 //=============================================================================
2250 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2251 const SMESH::long_array & IDsOfFixedNodes,
2252 CORBA::Long MaxNbOfIterations,
2253 CORBA::Double MaxAspectRatio,
2254 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2256 throw (SALOME::SALOME_Exception)
2261 TPythonDump aTPythonDump; // suppress dump in smooth()
2263 prepareIdSource( theObject );
2264 SMESH::long_array_var anElementsId = theObject->GetIDs();
2265 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2266 MaxAspectRatio, Method, IsParametric);
2268 // Update Python script
2269 aTPythonDump << "isDone = " << this << "."
2270 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2271 << theObject << ", " << IDsOfFixedNodes << ", "
2272 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2273 << "SMESH.SMESH_MeshEditor."
2274 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2275 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2279 SMESH_CATCH( SMESH::throwCorbaException );
2283 //=============================================================================
2287 //=============================================================================
2289 void SMESH_MeshEditor_i::RenumberNodes()
2290 throw (SALOME::SALOME_Exception)
2293 // Update Python script
2294 TPythonDump() << this << ".RenumberNodes()";
2296 getMeshDS()->Renumber( true );
2298 SMESH_CATCH( SMESH::throwCorbaException );
2301 //=============================================================================
2305 //=============================================================================
2307 void SMESH_MeshEditor_i::RenumberElements()
2308 throw (SALOME::SALOME_Exception)
2311 // Update Python script
2312 TPythonDump() << this << ".RenumberElements()";
2314 getMeshDS()->Renumber( false );
2316 SMESH_CATCH( SMESH::throwCorbaException );
2319 //=======================================================================
2321 * \brief Return groups by their IDs
2323 //=======================================================================
2325 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2326 throw (SALOME::SALOME_Exception)
2331 myMesh_i->CreateGroupServants();
2332 return myMesh_i->GetGroups( *groupIDs );
2334 SMESH_CATCH( SMESH::throwCorbaException );
2338 //=======================================================================
2339 //function : RotationSweepObjects
2341 //=======================================================================
2343 SMESH::ListOfGroups*
2344 SMESH_MeshEditor_i::RotationSweepObjects(const SMESH::ListOfIDSources & theNodes,
2345 const SMESH::ListOfIDSources & theEdges,
2346 const SMESH::ListOfIDSources & theFaces,
2347 const SMESH::AxisStruct & theAxis,
2348 CORBA::Double theAngleInRadians,
2349 CORBA::Long theNbOfSteps,
2350 CORBA::Double theTolerance,
2351 const bool theMakeGroups)
2352 throw (SALOME::SALOME_Exception)
2357 TIDSortedElemSet elemsNodes[2];
2358 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2359 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2360 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2362 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2363 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2364 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2365 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2367 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2368 bool makeWalls=true;
2369 if ( myIsPreviewMode )
2371 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2372 TPreviewMesh * tmpMesh = getPreviewMesh();
2373 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2374 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2375 workElements = & copyElements[0];
2376 //makeWalls = false; -- faces are needed for preview
2379 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2381 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2382 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2384 ::SMESH_MeshEditor::PGroupIDs groupIds =
2385 getEditor().RotationSweep (workElements, Ax1, theAngleInRadians,
2386 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2388 SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
2390 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2392 if ( !myIsPreviewMode )
2394 dumpGroupsList( aPythonDump, aGroups );
2395 aPythonDump << this<< ".RotationSweepObjects( "
2400 << TVar( theAngleInRadians ) << ", "
2401 << TVar( theNbOfSteps ) << ", "
2402 << TVar( theTolerance ) << ", "
2403 << theMakeGroups << " )";
2407 getPreviewMesh()->Remove( SMDSAbs_Volume );
2410 return aGroups ? aGroups : new SMESH::ListOfGroups;
2412 SMESH_CATCH( SMESH::throwCorbaException );
2416 namespace MeshEditor_I
2419 * \brief Structure used to pass extrusion parameters to ::SMESH_MeshEditor
2421 struct ExtrusionParams : public ::SMESH_MeshEditor::ExtrusParam
2423 bool myIsExtrusionByNormal;
2425 static int makeFlags( CORBA::Boolean MakeGroups,
2426 CORBA::Boolean ByAverageNormal = false,
2427 CORBA::Boolean UseInputElemsOnly = false,
2428 CORBA::Long Flags = 0,
2429 CORBA::Boolean MakeBoundary = true )
2431 if ( MakeGroups ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS;
2432 if ( ByAverageNormal ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BY_AVG_NORMAL;
2433 if ( UseInputElemsOnly) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY;
2434 if ( MakeBoundary ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BOUNDARY;
2438 ExtrusionParams(const SMESH::DirStruct & theDir,
2439 CORBA::Long theNbOfSteps,
2440 CORBA::Boolean theMakeGroups):
2441 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2445 makeFlags( theMakeGroups )),
2446 myIsExtrusionByNormal( false )
2450 ExtrusionParams(const SMESH::DirStruct & theDir,
2451 CORBA::Long theNbOfSteps,
2452 CORBA::Boolean theMakeGroups,
2453 CORBA::Long theExtrFlags,
2454 CORBA::Double theSewTolerance):
2455 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2459 makeFlags( theMakeGroups, false, false,
2460 theExtrFlags, false ),
2462 myIsExtrusionByNormal( false )
2465 // params for extrusion by normal
2466 ExtrusionParams(CORBA::Double theStepSize,
2467 CORBA::Long theNbOfSteps,
2468 CORBA::Short theDim,
2469 CORBA::Boolean theByAverageNormal,
2470 CORBA::Boolean theUseInputElemsOnly,
2471 CORBA::Boolean theMakeGroups ):
2472 ::SMESH_MeshEditor::ExtrusParam ( theStepSize,
2474 makeFlags( theMakeGroups,
2475 theByAverageNormal, theUseInputElemsOnly ),
2477 myIsExtrusionByNormal( true )
2483 Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS);
2488 //=======================================================================
2490 * \brief Generate dim+1 elements by extrusion of elements along vector
2491 * \param [in] edges - edges to extrude: a list including groups, sub-meshes or a mesh
2492 * \param [in] faces - faces to extrude: a list including groups, sub-meshes or a mesh
2493 * \param [in] nodes - nodes to extrude: a list including groups, sub-meshes or a mesh
2494 * \param [in] stepVector - vector giving direction and distance of an extrusion step
2495 * \param [in] nbOfSteps - number of elements to generate from one element
2496 * \param [in] toMakeGroups - if true, new elements will be included into new groups
2497 * corresponding to groups the input elements included in.
2498 * \return ListOfGroups - new groups craeted if \a toMakeGroups is true
2500 //=======================================================================
2502 SMESH::ListOfGroups*
2503 SMESH_MeshEditor_i::ExtrusionSweepObjects(const SMESH::ListOfIDSources & theNodes,
2504 const SMESH::ListOfIDSources & theEdges,
2505 const SMESH::ListOfIDSources & theFaces,
2506 const SMESH::DirStruct & theStepVector,
2507 CORBA::Long theNbOfSteps,
2508 CORBA::Boolean theToMakeGroups)
2509 throw (SALOME::SALOME_Exception)
2514 ExtrusionParams params( theStepVector, theNbOfSteps, theToMakeGroups );
2516 TIDSortedElemSet elemsNodes[2];
2517 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2518 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2519 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2521 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2522 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2523 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2524 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2526 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2527 SMDSAbs_ElementType previewType = SMDSAbs_All; //SMDSAbs_Face;
2528 if ( myIsPreviewMode )
2530 // if ( (*elemsNodes.begin())->GetType() == SMDSAbs_Node )
2531 // previewType = SMDSAbs_Edge;
2533 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2534 TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
2535 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2536 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2537 workElements = & copyElements[0];
2539 params.SetNoGroups();
2541 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2543 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2544 ::SMESH_MeshEditor::PGroupIDs groupIds =
2545 getEditor().ExtrusionSweep( workElements, params, aHistory );
2547 SMESH::ListOfGroups * aGroups = theToMakeGroups ? getGroups( groupIds.get()) : 0;
2549 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2551 if ( !myIsPreviewMode )
2553 dumpGroupsList( aPythonDump, aGroups );
2554 aPythonDump << this<< ".ExtrusionSweepObjects( "
2558 << theStepVector << ", "
2559 << TVar( theNbOfSteps ) << ", "
2560 << theToMakeGroups << " )";
2564 getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
2567 return aGroups ? aGroups : new SMESH::ListOfGroups;
2569 SMESH_CATCH( SMESH::throwCorbaException );
2573 //=======================================================================
2574 //function : ExtrusionByNormal
2576 //=======================================================================
2578 SMESH::ListOfGroups*
2579 SMESH_MeshEditor_i::ExtrusionByNormal(const SMESH::ListOfIDSources& objects,
2580 CORBA::Double stepSize,
2581 CORBA::Long nbOfSteps,
2582 CORBA::Boolean byAverageNormal,
2583 CORBA::Boolean useInputElemsOnly,
2584 CORBA::Boolean makeGroups,
2586 throw (SALOME::SALOME_Exception)
2591 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2593 ExtrusionParams params( stepSize, nbOfSteps, dim,
2594 byAverageNormal, useInputElemsOnly, makeGroups );
2596 SMDSAbs_ElementType elemType = ( dim == 1 ? SMDSAbs_Edge : SMDSAbs_Face );
2597 if ( objects.length() > 0 && !SMESH::DownCast<SMESH_Mesh_i*>( objects[0] ))
2599 SMESH::array_of_ElementType_var elemTypes = objects[0]->GetTypes();
2600 if (( elemTypes->length() == 1 ) &&
2601 ( elemTypes[0] == SMESH::EDGE || elemTypes[0] == SMESH::FACE ))
2602 elemType = ( SMDSAbs_ElementType ) elemTypes[0];
2605 TIDSortedElemSet elemsNodes[2];
2606 for ( int i = 0, nb = objects.length(); i < nb; ++i )
2607 idSourceToSet( objects[i], getMeshDS(), elemsNodes[0], elemType );
2609 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2610 SMDSAbs_ElementType previewType = SMDSAbs_Face;
2611 if ( myIsPreviewMode )
2613 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2614 TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
2615 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2616 workElements = & copyElements[0];
2618 params.SetNoGroups();
2621 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2622 ::SMESH_MeshEditor::PGroupIDs groupIds =
2623 getEditor().ExtrusionSweep( workElements, params, aHistory );
2625 SMESH::ListOfGroups * aGroups = makeGroups ? getGroups( groupIds.get()) : 0;
2627 if (!myIsPreviewMode) {
2628 dumpGroupsList(aPythonDump, aGroups);
2629 aPythonDump << this << ".ExtrusionByNormal( " << objects
2630 << ", " << TVar( stepSize )
2631 << ", " << TVar( nbOfSteps )
2632 << ", " << byAverageNormal
2633 << ", " << useInputElemsOnly
2634 << ", " << makeGroups
2640 getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
2643 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2645 return aGroups ? aGroups : new SMESH::ListOfGroups;
2647 SMESH_CATCH( SMESH::throwCorbaException );
2651 //=======================================================================
2652 //function : AdvancedExtrusion
2654 //=======================================================================
2656 SMESH::ListOfGroups*
2657 SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2658 const SMESH::DirStruct & theStepVector,
2659 CORBA::Long theNbOfSteps,
2660 CORBA::Long theExtrFlags,
2661 CORBA::Double theSewTolerance,
2662 CORBA::Boolean theMakeGroups)
2663 throw (SALOME::SALOME_Exception)
2668 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2670 ExtrusionParams params( theStepVector, theNbOfSteps, theMakeGroups,
2671 theExtrFlags, theSewTolerance );
2673 TIDSortedElemSet elemsNodes[2];
2674 arrayToSet( theIDsOfElements, getMeshDS(), elemsNodes[0] );
2676 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2677 ::SMESH_MeshEditor::PGroupIDs groupIds =
2678 getEditor().ExtrusionSweep( elemsNodes, params, aHistory );
2680 SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
2682 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2684 if ( !myIsPreviewMode ) {
2685 dumpGroupsList(aPythonDump, aGroups);
2686 aPythonDump << this << ".AdvancedExtrusion( "
2687 << theIDsOfElements << ", "
2688 << theStepVector << ", "
2689 << theNbOfSteps << ", "
2690 << theExtrFlags << ", "
2691 << theSewTolerance << ", "
2692 << theMakeGroups << " )";
2696 getPreviewMesh()->Remove( SMDSAbs_Volume );
2699 return aGroups ? aGroups : new SMESH::ListOfGroups;
2701 SMESH_CATCH( SMESH::throwCorbaException );
2705 //================================================================================
2707 * \brief Convert extrusion error to IDL enum
2709 //================================================================================
2713 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2715 SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( ::SMESH_MeshEditor::Extrusion_Error e )
2719 RETCASE( EXTR_NO_ELEMENTS );
2720 RETCASE( EXTR_PATH_NOT_EDGE );
2721 RETCASE( EXTR_BAD_PATH_SHAPE );
2722 RETCASE( EXTR_BAD_STARTING_NODE );
2723 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2724 RETCASE( EXTR_CANT_GET_TANGENT );
2726 return SMESH::SMESH_MeshEditor::EXTR_OK;
2730 //=======================================================================
2731 //function : extrusionAlongPath
2733 //=======================================================================
2734 SMESH::ListOfGroups*
2735 SMESH_MeshEditor_i::ExtrusionAlongPathObjects(const SMESH::ListOfIDSources & theNodes,
2736 const SMESH::ListOfIDSources & theEdges,
2737 const SMESH::ListOfIDSources & theFaces,
2738 SMESH::SMESH_IDSource_ptr thePathMesh,
2739 GEOM::GEOM_Object_ptr thePathShape,
2740 CORBA::Long theNodeStart,
2741 CORBA::Boolean theHasAngles,
2742 const SMESH::double_array & theAngles,
2743 CORBA::Boolean theLinearVariation,
2744 CORBA::Boolean theHasRefPoint,
2745 const SMESH::PointStruct & theRefPoint,
2747 SMESH::SMESH_MeshEditor::Extrusion_Error& theError)
2748 throw (SALOME::SALOME_Exception)
2753 SMESH::ListOfGroups_var aGroups = new SMESH::ListOfGroups;
2755 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2756 if ( thePathMesh->_is_nil() )
2757 return aGroups._retn();
2760 SMESH_subMesh* aSubMesh = 0;
2761 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2762 if ( thePathShape->_is_nil() )
2764 // thePathMesh should be either a sub-mesh or a mesh with 1D elements only
2765 if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( thePathMesh ))
2767 SMESH::SMESH_Mesh_var mesh = thePathMesh->GetMesh();
2768 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
2769 if ( !aMeshImp ) return aGroups._retn();
2770 aSubMesh = aMeshImp->GetImpl().GetSubMeshContaining( sm->GetId() );
2771 if ( !aSubMesh ) return aGroups._retn();
2773 else if ( !aMeshImp ||
2774 aMeshImp->NbEdges() != aMeshImp->NbElements() )
2776 return aGroups._retn();
2781 if ( !aMeshImp ) return aGroups._retn();
2782 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2783 aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2784 if ( !aSubMesh || !aSubMesh->GetSubMeshDS() )
2785 return aGroups._retn();
2788 SMDS_MeshNode* nodeStart =
2789 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2791 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2792 return aGroups._retn();
2795 TIDSortedElemSet elemsNodes[2];
2796 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2797 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2798 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2800 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2801 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2802 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2803 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2805 list<double> angles;
2806 for (int i = 0; i < theAngles.length(); i++) {
2807 angles.push_back( theAngles[i] );
2810 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2812 int nbOldGroups = myMesh->NbGroup();
2814 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2815 if ( myIsPreviewMode )
2817 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2818 TPreviewMesh * tmpMesh = getPreviewMesh();
2819 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2820 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2821 workElements = & copyElements[0];
2822 theMakeGroups = false;
2825 ::SMESH_MeshEditor::Extrusion_Error error;
2827 error = getEditor().ExtrusionAlongTrack( workElements, &(aMeshImp->GetImpl()), nodeStart,
2828 theHasAngles, angles, theLinearVariation,
2829 theHasRefPoint, refPnt, theMakeGroups );
2831 error = getEditor().ExtrusionAlongTrack( workElements, aSubMesh, nodeStart,
2832 theHasAngles, angles, theLinearVariation,
2833 theHasRefPoint, refPnt, theMakeGroups );
2835 declareMeshModified( /*isReComputeSafe=*/true );
2836 theError = convExtrError( error );
2838 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2839 if ( theMakeGroups ) {
2840 list<int> groupIDs = myMesh->GetGroupIds();
2841 list<int>::iterator newBegin = groupIDs.begin();
2842 std::advance( newBegin, nbOldGroups ); // skip old groups
2843 groupIDs.erase( groupIDs.begin(), newBegin );
2844 aGroups = getGroups( & groupIDs );
2845 if ( ! &aGroups.in() ) aGroups = new SMESH::ListOfGroups;
2848 if ( !myIsPreviewMode ) {
2849 aPythonDump << "(" << aGroups << ", error) = "
2850 << this << ".ExtrusionAlongPathObjects( "
2854 << thePathMesh << ", "
2855 << thePathShape << ", "
2856 << theNodeStart << ", "
2857 << theHasAngles << ", "
2858 << theAngles << ", "
2859 << theLinearVariation << ", "
2860 << theHasRefPoint << ", "
2861 << "SMESH.PointStruct( "
2862 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2863 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2864 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ), "
2865 << theMakeGroups << " )";
2869 getPreviewMesh()->Remove( SMDSAbs_Volume );
2872 return aGroups._retn();
2874 SMESH_CATCH( SMESH::throwCorbaException );
2878 //================================================================================
2880 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
2881 * of given angles along path steps
2882 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
2883 * which proceeds the extrusion
2884 * \param PathShape is shape(edge); as the mesh can be complex, the edge
2885 * is used to define the sub-mesh for the path
2887 //================================================================================
2889 SMESH::double_array*
2890 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
2891 GEOM::GEOM_Object_ptr thePathShape,
2892 const SMESH::double_array & theAngles)
2894 SMESH::double_array_var aResult = new SMESH::double_array();
2895 int nbAngles = theAngles.length();
2896 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
2898 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2899 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2900 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2901 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
2902 return aResult._retn();
2903 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
2904 if ( nbSteps == nbAngles )
2906 aResult.inout() = theAngles;
2910 aResult->length( nbSteps );
2911 double rAn2St = double( nbAngles ) / double( nbSteps );
2912 double angPrev = 0, angle;
2913 for ( int iSt = 0; iSt < nbSteps; ++iSt )
2915 double angCur = rAn2St * ( iSt+1 );
2916 double angCurFloor = floor( angCur );
2917 double angPrevFloor = floor( angPrev );
2918 if ( angPrevFloor == angCurFloor )
2919 angle = rAn2St * theAngles[ int( angCurFloor ) ];
2922 int iP = int( angPrevFloor );
2923 double angPrevCeil = ceil(angPrev);
2924 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
2926 int iC = int( angCurFloor );
2927 if ( iC < nbAngles )
2928 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
2930 iP = int( angPrevCeil );
2932 angle += theAngles[ iC ];
2934 aResult[ iSt ] = angle;
2939 // Update Python script
2940 TPythonDump() << "rotAngles = " << theAngles;
2941 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
2942 << thePathMesh << ", "
2943 << thePathShape << ", "
2946 return aResult._retn();
2949 //=======================================================================
2952 //=======================================================================
2954 SMESH::ListOfGroups*
2955 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
2956 const SMESH::AxisStruct & theAxis,
2957 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2958 CORBA::Boolean theCopy,
2960 ::SMESH_Mesh* theTargetMesh)
2961 throw (SALOME::SALOME_Exception)
2966 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
2967 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
2969 if ( theTargetMesh )
2973 switch ( theMirrorType ) {
2974 case SMESH::SMESH_MeshEditor::POINT:
2975 aTrsf.SetMirror( P );
2977 case SMESH::SMESH_MeshEditor::AXIS:
2978 aTrsf.SetMirror( gp_Ax1( P, V ));
2981 aTrsf.SetMirror( gp_Ax2( P, V ));
2984 TIDSortedElemSet copyElements;
2985 TIDSortedElemSet* workElements = & theElements;
2987 if ( myIsPreviewMode )
2989 TPreviewMesh * tmpMesh = getPreviewMesh();
2990 tmpMesh->Copy( theElements, copyElements);
2991 if ( !theCopy && !theTargetMesh )
2993 TIDSortedElemSet elemsAround, elemsAroundCopy;
2994 getElementsAround( theElements, getMeshDS(), elemsAround );
2995 tmpMesh->Copy( elemsAround, elemsAroundCopy);
2997 workElements = & copyElements;
2998 theMakeGroups = false;
3001 ::SMESH_MeshEditor::PGroupIDs groupIds =
3002 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3004 if ( theCopy && !myIsPreviewMode)
3006 if ( theTargetMesh )
3008 theTargetMesh->GetMeshDS()->Modified();
3012 declareMeshModified( /*isReComputeSafe=*/false );
3015 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3017 SMESH_CATCH( SMESH::throwCorbaException );
3021 //=======================================================================
3024 //=======================================================================
3026 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3027 const SMESH::AxisStruct & theAxis,
3028 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3029 CORBA::Boolean theCopy)
3030 throw (SALOME::SALOME_Exception)
3032 if ( !myIsPreviewMode ) {
3033 TPythonDump() << this << ".Mirror( "
3034 << theIDsOfElements << ", "
3036 << mirrorTypeName(theMirrorType) << ", "
3039 if ( theIDsOfElements.length() > 0 )
3041 TIDSortedElemSet elements;
3042 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3043 mirror(elements, theAxis, theMirrorType, theCopy, false);
3048 //=======================================================================
3049 //function : MirrorObject
3051 //=======================================================================
3053 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3054 const SMESH::AxisStruct & theAxis,
3055 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3056 CORBA::Boolean theCopy)
3057 throw (SALOME::SALOME_Exception)
3059 if ( !myIsPreviewMode ) {
3060 TPythonDump() << this << ".MirrorObject( "
3061 << theObject << ", "
3063 << mirrorTypeName(theMirrorType) << ", "
3066 TIDSortedElemSet elements;
3068 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3070 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3071 mirror(elements, theAxis, theMirrorType, theCopy, false);
3074 //=======================================================================
3075 //function : MirrorMakeGroups
3077 //=======================================================================
3079 SMESH::ListOfGroups*
3080 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3081 const SMESH::AxisStruct& theMirror,
3082 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3083 throw (SALOME::SALOME_Exception)
3085 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3087 SMESH::ListOfGroups * aGroups = 0;
3088 if ( theIDsOfElements.length() > 0 )
3090 TIDSortedElemSet elements;
3091 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3092 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3094 if (!myIsPreviewMode) {
3095 dumpGroupsList(aPythonDump, aGroups);
3096 aPythonDump << this << ".MirrorMakeGroups( "
3097 << theIDsOfElements << ", "
3098 << theMirror << ", "
3099 << mirrorTypeName(theMirrorType) << " )";
3104 //=======================================================================
3105 //function : MirrorObjectMakeGroups
3107 //=======================================================================
3109 SMESH::ListOfGroups*
3110 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3111 const SMESH::AxisStruct& theMirror,
3112 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3113 throw (SALOME::SALOME_Exception)
3115 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3117 SMESH::ListOfGroups * aGroups = 0;
3118 TIDSortedElemSet elements;
3119 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3120 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3122 if (!myIsPreviewMode)
3124 dumpGroupsList(aPythonDump,aGroups);
3125 aPythonDump << this << ".MirrorObjectMakeGroups( "
3126 << theObject << ", "
3127 << theMirror << ", "
3128 << mirrorTypeName(theMirrorType) << " )";
3133 //=======================================================================
3134 //function : MirrorMakeMesh
3136 //=======================================================================
3138 SMESH::SMESH_Mesh_ptr
3139 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3140 const SMESH::AxisStruct& theMirror,
3141 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3142 CORBA::Boolean theCopyGroups,
3143 const char* theMeshName)
3144 throw (SALOME::SALOME_Exception)
3146 SMESH_Mesh_i* mesh_i;
3147 SMESH::SMESH_Mesh_var mesh;
3148 { // open new scope to dump "MakeMesh" command
3149 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3151 TPythonDump pydump; // to prevent dump at mesh creation
3153 mesh = makeMesh( theMeshName );
3154 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3155 if (mesh_i && theIDsOfElements.length() > 0 )
3157 TIDSortedElemSet elements;
3158 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3159 mirror(elements, theMirror, theMirrorType,
3160 false, theCopyGroups, & mesh_i->GetImpl());
3161 mesh_i->CreateGroupServants();
3164 if (!myIsPreviewMode) {
3165 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3166 << theIDsOfElements << ", "
3167 << theMirror << ", "
3168 << mirrorTypeName(theMirrorType) << ", "
3169 << theCopyGroups << ", '"
3170 << theMeshName << "' )";
3175 if (!myIsPreviewMode && mesh_i)
3176 mesh_i->GetGroups();
3178 return mesh._retn();
3181 //=======================================================================
3182 //function : MirrorObjectMakeMesh
3184 //=======================================================================
3186 SMESH::SMESH_Mesh_ptr
3187 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3188 const SMESH::AxisStruct& theMirror,
3189 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3190 CORBA::Boolean theCopyGroups,
3191 const char* theMeshName)
3192 throw (SALOME::SALOME_Exception)
3194 SMESH_Mesh_i* mesh_i;
3195 SMESH::SMESH_Mesh_var mesh;
3196 { // open new scope to dump "MakeMesh" command
3197 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3199 TPythonDump pydump; // to prevent dump at mesh creation
3201 mesh = makeMesh( theMeshName );
3202 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3203 TIDSortedElemSet elements;
3205 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3207 mirror(elements, theMirror, theMirrorType,
3208 false, theCopyGroups, & mesh_i->GetImpl());
3209 mesh_i->CreateGroupServants();
3211 if (!myIsPreviewMode) {
3212 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3213 << theObject << ", "
3214 << theMirror << ", "
3215 << mirrorTypeName(theMirrorType) << ", "
3216 << theCopyGroups << ", '"
3217 << theMeshName << "' )";
3222 if (!myIsPreviewMode && mesh_i)
3223 mesh_i->GetGroups();
3225 return mesh._retn();
3228 //=======================================================================
3229 //function : translate
3231 //=======================================================================
3233 SMESH::ListOfGroups*
3234 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3235 const SMESH::DirStruct & theVector,
3236 CORBA::Boolean theCopy,
3238 ::SMESH_Mesh* theTargetMesh)
3239 throw (SALOME::SALOME_Exception)
3244 if ( theTargetMesh )
3248 const SMESH::PointStruct * P = &theVector.PS;
3249 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3251 TIDSortedElemSet copyElements;
3252 TIDSortedElemSet* workElements = &theElements;
3254 if ( myIsPreviewMode )
3256 TPreviewMesh * tmpMesh = getPreviewMesh();
3257 tmpMesh->Copy( theElements, copyElements);
3258 if ( !theCopy && !theTargetMesh )
3260 TIDSortedElemSet elemsAround, elemsAroundCopy;
3261 getElementsAround( theElements, getMeshDS(), elemsAround );
3262 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3264 workElements = & copyElements;
3265 theMakeGroups = false;
3268 ::SMESH_MeshEditor::PGroupIDs groupIds =
3269 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3271 if ( theCopy && !myIsPreviewMode )
3273 if ( theTargetMesh )
3275 theTargetMesh->GetMeshDS()->Modified();
3279 declareMeshModified( /*isReComputeSafe=*/false );
3283 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3285 SMESH_CATCH( SMESH::throwCorbaException );
3289 //=======================================================================
3290 //function : Translate
3292 //=======================================================================
3294 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3295 const SMESH::DirStruct & theVector,
3296 CORBA::Boolean theCopy)
3297 throw (SALOME::SALOME_Exception)
3299 if (!myIsPreviewMode) {
3300 TPythonDump() << this << ".Translate( "
3301 << theIDsOfElements << ", "
3302 << theVector << ", "
3305 if (theIDsOfElements.length()) {
3306 TIDSortedElemSet elements;
3307 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3308 translate(elements, theVector, theCopy, false);
3312 //=======================================================================
3313 //function : TranslateObject
3315 //=======================================================================
3317 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3318 const SMESH::DirStruct & theVector,
3319 CORBA::Boolean theCopy)
3320 throw (SALOME::SALOME_Exception)
3322 if (!myIsPreviewMode) {
3323 TPythonDump() << this << ".TranslateObject( "
3324 << theObject << ", "
3325 << theVector << ", "
3328 TIDSortedElemSet elements;
3330 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3332 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3333 translate(elements, theVector, theCopy, false);
3336 //=======================================================================
3337 //function : TranslateMakeGroups
3339 //=======================================================================
3341 SMESH::ListOfGroups*
3342 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3343 const SMESH::DirStruct& theVector)
3344 throw (SALOME::SALOME_Exception)
3346 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3348 SMESH::ListOfGroups * aGroups = 0;
3349 if (theIDsOfElements.length()) {
3350 TIDSortedElemSet elements;
3351 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3352 aGroups = translate(elements,theVector,true,true);
3354 if (!myIsPreviewMode) {
3355 dumpGroupsList(aPythonDump, aGroups);
3356 aPythonDump << this << ".TranslateMakeGroups( "
3357 << theIDsOfElements << ", "
3358 << theVector << " )";
3363 //=======================================================================
3364 //function : TranslateObjectMakeGroups
3366 //=======================================================================
3368 SMESH::ListOfGroups*
3369 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3370 const SMESH::DirStruct& theVector)
3371 throw (SALOME::SALOME_Exception)
3373 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3375 SMESH::ListOfGroups * aGroups = 0;
3376 TIDSortedElemSet elements;
3377 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3378 aGroups = translate(elements, theVector, true, true);
3380 if (!myIsPreviewMode) {
3381 dumpGroupsList(aPythonDump, aGroups);
3382 aPythonDump << this << ".TranslateObjectMakeGroups( "
3383 << theObject << ", "
3384 << theVector << " )";
3389 //=======================================================================
3390 //function : TranslateMakeMesh
3392 //=======================================================================
3394 SMESH::SMESH_Mesh_ptr
3395 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3396 const SMESH::DirStruct& theVector,
3397 CORBA::Boolean theCopyGroups,
3398 const char* theMeshName)
3399 throw (SALOME::SALOME_Exception)
3401 SMESH_Mesh_i* mesh_i;
3402 SMESH::SMESH_Mesh_var mesh;
3404 { // open new scope to dump "MakeMesh" command
3405 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3407 TPythonDump pydump; // to prevent dump at mesh creation
3409 mesh = makeMesh( theMeshName );
3410 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3412 if ( mesh_i && theIDsOfElements.length() )
3414 TIDSortedElemSet elements;
3415 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3416 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3417 mesh_i->CreateGroupServants();
3420 if ( !myIsPreviewMode ) {
3421 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3422 << theIDsOfElements << ", "
3423 << theVector << ", "
3424 << theCopyGroups << ", '"
3425 << theMeshName << "' )";
3430 if (!myIsPreviewMode && mesh_i)
3431 mesh_i->GetGroups();
3433 return mesh._retn();
3436 //=======================================================================
3437 //function : TranslateObjectMakeMesh
3439 //=======================================================================
3441 SMESH::SMESH_Mesh_ptr
3442 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3443 const SMESH::DirStruct& theVector,
3444 CORBA::Boolean theCopyGroups,
3445 const char* theMeshName)
3446 throw (SALOME::SALOME_Exception)
3449 SMESH_Mesh_i* mesh_i;
3450 SMESH::SMESH_Mesh_var mesh;
3451 { // open new scope to dump "MakeMesh" command
3452 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3454 TPythonDump pydump; // to prevent dump at mesh creation
3455 mesh = makeMesh( theMeshName );
3456 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3458 TIDSortedElemSet elements;
3460 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3462 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3463 mesh_i->CreateGroupServants();
3465 if ( !myIsPreviewMode ) {
3466 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3467 << theObject << ", "
3468 << theVector << ", "
3469 << theCopyGroups << ", '"
3470 << theMeshName << "' )";
3475 if (!myIsPreviewMode && mesh_i)
3476 mesh_i->GetGroups();
3478 return mesh._retn();
3480 SMESH_CATCH( SMESH::throwCorbaException );
3484 //=======================================================================
3487 //=======================================================================
3489 SMESH::ListOfGroups*
3490 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3491 const SMESH::AxisStruct & theAxis,
3492 CORBA::Double theAngle,
3493 CORBA::Boolean theCopy,
3495 ::SMESH_Mesh* theTargetMesh)
3496 throw (SALOME::SALOME_Exception)
3501 if ( theTargetMesh )
3504 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3505 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3508 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3510 TIDSortedElemSet copyElements;
3511 TIDSortedElemSet* workElements = &theElements;
3512 if ( myIsPreviewMode ) {
3513 TPreviewMesh * tmpMesh = getPreviewMesh();
3514 tmpMesh->Copy( theElements, copyElements );
3515 if ( !theCopy && !theTargetMesh )
3517 TIDSortedElemSet elemsAround, elemsAroundCopy;
3518 getElementsAround( theElements, getMeshDS(), elemsAround );
3519 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3521 workElements = ©Elements;
3522 theMakeGroups = false;
3525 ::SMESH_MeshEditor::PGroupIDs groupIds =
3526 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3528 if ( theCopy && !myIsPreviewMode)
3530 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
3531 else declareMeshModified( /*isReComputeSafe=*/false );
3534 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3536 SMESH_CATCH( SMESH::throwCorbaException );
3540 //=======================================================================
3543 //=======================================================================
3545 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
3546 const SMESH::AxisStruct & theAxis,
3547 CORBA::Double theAngle,
3548 CORBA::Boolean theCopy)
3549 throw (SALOME::SALOME_Exception)
3551 if (!myIsPreviewMode) {
3552 TPythonDump() << this << ".Rotate( "
3553 << theIDsOfElements << ", "
3555 << TVar( theAngle ) << ", "
3558 if (theIDsOfElements.length() > 0)
3560 TIDSortedElemSet elements;
3561 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3562 rotate(elements,theAxis,theAngle,theCopy,false);
3566 //=======================================================================
3567 //function : RotateObject
3569 //=======================================================================
3571 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
3572 const SMESH::AxisStruct & theAxis,
3573 CORBA::Double theAngle,
3574 CORBA::Boolean theCopy)
3575 throw (SALOME::SALOME_Exception)
3577 if ( !myIsPreviewMode ) {
3578 TPythonDump() << this << ".RotateObject( "
3579 << theObject << ", "
3581 << TVar( theAngle ) << ", "
3584 TIDSortedElemSet elements;
3585 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3586 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3587 rotate(elements,theAxis,theAngle,theCopy,false);
3590 //=======================================================================
3591 //function : RotateMakeGroups
3593 //=======================================================================
3595 SMESH::ListOfGroups*
3596 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
3597 const SMESH::AxisStruct& theAxis,
3598 CORBA::Double theAngle)
3599 throw (SALOME::SALOME_Exception)
3601 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3603 SMESH::ListOfGroups * aGroups = 0;
3604 if (theIDsOfElements.length() > 0)
3606 TIDSortedElemSet elements;
3607 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3608 aGroups = rotate(elements,theAxis,theAngle,true,true);
3610 if (!myIsPreviewMode) {
3611 dumpGroupsList(aPythonDump, aGroups);
3612 aPythonDump << this << ".RotateMakeGroups( "
3613 << theIDsOfElements << ", "
3615 << TVar( theAngle ) << " )";
3620 //=======================================================================
3621 //function : RotateObjectMakeGroups
3623 //=======================================================================
3625 SMESH::ListOfGroups*
3626 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3627 const SMESH::AxisStruct& theAxis,
3628 CORBA::Double theAngle)
3629 throw (SALOME::SALOME_Exception)
3631 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3633 SMESH::ListOfGroups * aGroups = 0;
3634 TIDSortedElemSet elements;
3635 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3636 aGroups = rotate(elements, theAxis, theAngle, true, true);
3638 if (!myIsPreviewMode) {
3639 dumpGroupsList(aPythonDump, aGroups);
3640 aPythonDump << this << ".RotateObjectMakeGroups( "
3641 << theObject << ", "
3643 << TVar( theAngle ) << " )";
3648 //=======================================================================
3649 //function : RotateMakeMesh
3651 //=======================================================================
3653 SMESH::SMESH_Mesh_ptr
3654 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
3655 const SMESH::AxisStruct& theAxis,
3656 CORBA::Double theAngleInRadians,
3657 CORBA::Boolean theCopyGroups,
3658 const char* theMeshName)
3659 throw (SALOME::SALOME_Exception)
3662 SMESH::SMESH_Mesh_var mesh;
3663 SMESH_Mesh_i* mesh_i;
3665 { // open new scope to dump "MakeMesh" command
3666 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3668 TPythonDump pydump; // to prevent dump at mesh creation
3670 mesh = makeMesh( theMeshName );
3671 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3673 if ( mesh_i && theIDsOfElements.length() > 0 )
3675 TIDSortedElemSet elements;
3676 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3677 rotate(elements, theAxis, theAngleInRadians,
3678 false, theCopyGroups, & mesh_i->GetImpl());
3679 mesh_i->CreateGroupServants();
3681 if ( !myIsPreviewMode ) {
3682 pydump << mesh << " = " << this << ".RotateMakeMesh( "
3683 << theIDsOfElements << ", "
3685 << TVar( theAngleInRadians ) << ", "
3686 << theCopyGroups << ", '"
3687 << theMeshName << "' )";
3692 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
3693 mesh_i->GetGroups();
3695 return mesh._retn();
3697 SMESH_CATCH( SMESH::throwCorbaException );
3701 //=======================================================================
3702 //function : RotateObjectMakeMesh
3704 //=======================================================================
3706 SMESH::SMESH_Mesh_ptr
3707 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3708 const SMESH::AxisStruct& theAxis,
3709 CORBA::Double theAngleInRadians,
3710 CORBA::Boolean theCopyGroups,
3711 const char* theMeshName)
3712 throw (SALOME::SALOME_Exception)
3715 SMESH::SMESH_Mesh_var mesh;
3716 SMESH_Mesh_i* mesh_i;
3718 {// open new scope to dump "MakeMesh" command
3719 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3721 TPythonDump pydump; // to prevent dump at mesh creation
3722 mesh = makeMesh( theMeshName );
3723 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3725 TIDSortedElemSet elements;
3727 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3729 rotate(elements, theAxis, theAngleInRadians,
3730 false, theCopyGroups, & mesh_i->GetImpl());
3731 mesh_i->CreateGroupServants();
3733 if ( !myIsPreviewMode ) {
3734 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
3735 << theObject << ", "
3737 << TVar( theAngleInRadians ) << ", "
3738 << theCopyGroups << ", '"
3739 << theMeshName << "' )";
3744 if (!myIsPreviewMode && mesh_i)
3745 mesh_i->GetGroups();
3747 return mesh._retn();
3749 SMESH_CATCH( SMESH::throwCorbaException );
3753 //=======================================================================
3756 //=======================================================================
3758 SMESH::ListOfGroups*
3759 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
3760 const SMESH::PointStruct& thePoint,
3761 const SMESH::double_array& theScaleFact,
3762 CORBA::Boolean theCopy,
3764 ::SMESH_Mesh* theTargetMesh)
3765 throw (SALOME::SALOME_Exception)
3769 if ( theScaleFact.length() < 1 )
3770 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
3771 if ( theScaleFact.length() == 2 )
3772 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
3774 if ( theTargetMesh )
3777 TIDSortedElemSet elements;
3778 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3779 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3784 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
3785 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
3789 #if OCC_VERSION_LARGE > 0x06070100
3790 // fight against orthogonalization
3791 // aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
3792 // 0, S[1], 0, thePoint.y * (1-S[1]),
3793 // 0, 0, S[2], thePoint.z * (1-S[2]) );
3794 aTrsf.SetScale( gp::Origin(), 1.0 ); // set form which is used to make group names
3795 gp_XYZ & loc = ( gp_XYZ& ) aTrsf.TranslationPart();
3796 gp_Mat & M = ( gp_Mat& ) aTrsf.HVectorialPart();
3797 loc.SetCoord( thePoint.x * (1-S[0]),
3798 thePoint.y * (1-S[1]),
3799 thePoint.z * (1-S[2]));
3800 M.SetDiagonal( S[0], S[1], S[2] );
3803 double tol = std::numeric_limits<double>::max();
3804 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
3805 0, S[1], 0, thePoint.y * (1-S[1]),
3806 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
3809 TIDSortedElemSet copyElements;
3810 TIDSortedElemSet* workElements = &elements;
3811 if ( myIsPreviewMode )
3813 TPreviewMesh * tmpMesh = getPreviewMesh();
3814 tmpMesh->Copy( elements, copyElements);
3815 if ( !theCopy && !theTargetMesh )
3817 TIDSortedElemSet elemsAround, elemsAroundCopy;
3818 getElementsAround( elements, getMeshDS(), elemsAround );
3819 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3821 workElements = & copyElements;
3822 theMakeGroups = false;
3825 ::SMESH_MeshEditor::PGroupIDs groupIds =
3826 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3828 if ( theCopy && !myIsPreviewMode )
3830 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
3831 else declareMeshModified( /*isReComputeSafe=*/false );
3833 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3835 SMESH_CATCH( SMESH::throwCorbaException );
3839 //=======================================================================
3842 //=======================================================================
3844 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
3845 const SMESH::PointStruct& thePoint,
3846 const SMESH::double_array& theScaleFact,
3847 CORBA::Boolean theCopy)
3848 throw (SALOME::SALOME_Exception)
3850 if ( !myIsPreviewMode ) {
3851 TPythonDump() << this << ".Scale( "
3852 << theObject << ", "
3854 << TVar( theScaleFact ) << ", "
3857 scale(theObject, thePoint, theScaleFact, theCopy, false);
3861 //=======================================================================
3862 //function : ScaleMakeGroups
3864 //=======================================================================
3866 SMESH::ListOfGroups*
3867 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3868 const SMESH::PointStruct& thePoint,
3869 const SMESH::double_array& theScaleFact)
3870 throw (SALOME::SALOME_Exception)
3872 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3874 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
3875 if (!myIsPreviewMode) {
3876 dumpGroupsList(aPythonDump, aGroups);
3877 aPythonDump << this << ".Scale("
3880 << TVar( theScaleFact ) << ",True,True)";
3886 //=======================================================================
3887 //function : ScaleMakeMesh
3889 //=======================================================================
3891 SMESH::SMESH_Mesh_ptr
3892 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3893 const SMESH::PointStruct& thePoint,
3894 const SMESH::double_array& theScaleFact,
3895 CORBA::Boolean theCopyGroups,
3896 const char* theMeshName)
3897 throw (SALOME::SALOME_Exception)
3899 SMESH_Mesh_i* mesh_i;
3900 SMESH::SMESH_Mesh_var mesh;
3901 { // open new scope to dump "MakeMesh" command
3902 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3904 TPythonDump pydump; // to prevent dump at mesh creation
3905 mesh = makeMesh( theMeshName );
3906 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3910 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
3911 mesh_i->CreateGroupServants();
3913 if ( !myIsPreviewMode )
3914 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
3915 << theObject << ", "
3917 << TVar( theScaleFact ) << ", "
3918 << theCopyGroups << ", '"
3919 << theMeshName << "' )";
3923 if (!myIsPreviewMode && mesh_i)
3924 mesh_i->GetGroups();
3926 return mesh._retn();
3930 //=======================================================================
3931 //function : FindCoincidentNodes
3933 //=======================================================================
3935 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
3936 SMESH::array_of_long_array_out GroupsOfNodes)
3937 throw (SALOME::SALOME_Exception)
3942 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3943 TIDSortedNodeSet nodes; // no input nodes
3944 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3946 GroupsOfNodes = new SMESH::array_of_long_array;
3947 GroupsOfNodes->length( aListOfListOfNodes.size() );
3948 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3949 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
3950 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3951 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3952 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3953 aGroup.length( aListOfNodes.size() );
3954 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3955 aGroup[ j ] = (*lIt)->GetID();
3957 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
3958 << Tolerance << " )";
3960 SMESH_CATCH( SMESH::throwCorbaException );
3963 //=======================================================================
3964 //function : FindCoincidentNodesOnPart
3966 //=======================================================================
3968 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
3969 CORBA::Double Tolerance,
3970 SMESH::array_of_long_array_out GroupsOfNodes)
3971 throw (SALOME::SALOME_Exception)
3976 TIDSortedNodeSet nodes;
3977 idSourceToNodeSet( theObject, getMeshDS(), nodes );
3979 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3981 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3983 GroupsOfNodes = new SMESH::array_of_long_array;
3984 GroupsOfNodes->length( aListOfListOfNodes.size() );
3985 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3986 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
3988 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3989 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3990 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3991 aGroup.length( aListOfNodes.size() );
3992 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3993 aGroup[ j ] = (*lIt)->GetID();
3995 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
3997 << Tolerance << " )";
3999 SMESH_CATCH( SMESH::throwCorbaException );
4002 //================================================================================
4004 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4005 * ExceptSubMeshOrGroups
4007 //================================================================================
4009 void SMESH_MeshEditor_i::
4010 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4011 CORBA::Double theTolerance,
4012 SMESH::array_of_long_array_out theGroupsOfNodes,
4013 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4014 throw (SALOME::SALOME_Exception)
4019 TIDSortedNodeSet nodes;
4020 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4022 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4024 TIDSortedNodeSet exceptNodes;
4025 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
4026 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4027 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4028 nodes.erase( *avoidNode );
4030 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4032 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4034 theGroupsOfNodes = new SMESH::array_of_long_array;
4035 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4036 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4037 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4039 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4040 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4041 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4042 aGroup.length( aListOfNodes.size() );
4043 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4044 aGroup[ j ] = (*lIt)->GetID();
4046 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4048 << theTolerance << ", "
4049 << theExceptSubMeshOrGroups << " )";
4051 SMESH_CATCH( SMESH::throwCorbaException );
4054 //=======================================================================
4055 //function : MergeNodes
4057 //=======================================================================
4059 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4060 throw (SALOME::SALOME_Exception)
4065 SMESHDS_Mesh* aMesh = getMeshDS();
4067 TPythonDump aTPythonDump;
4068 aTPythonDump << this << ".MergeNodes([";
4069 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4070 for (int i = 0; i < GroupsOfNodes.length(); i++)
4072 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4073 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4074 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4075 for ( int j = 0; j < aNodeGroup.length(); j++ )
4077 CORBA::Long index = aNodeGroup[ j ];
4078 const SMDS_MeshNode * node = aMesh->FindNode(index);
4080 aListOfNodes.push_back( node );
4082 if ( aListOfNodes.size() < 2 )
4083 aListOfListOfNodes.pop_back();
4085 if ( i > 0 ) aTPythonDump << ", ";
4086 aTPythonDump << aNodeGroup;
4088 getEditor().MergeNodes( aListOfListOfNodes );
4090 aTPythonDump << "])";
4092 declareMeshModified( /*isReComputeSafe=*/false );
4094 SMESH_CATCH( SMESH::throwCorbaException );
4097 //=======================================================================
4098 //function : FindEqualElements
4100 //=======================================================================
4102 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4103 SMESH::array_of_long_array_out GroupsOfElementsID)
4104 throw (SALOME::SALOME_Exception)
4109 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4110 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4112 TIDSortedElemSet elems;
4113 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4115 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4116 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
4118 GroupsOfElementsID = new SMESH::array_of_long_array;
4119 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4121 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4122 aListOfListOfElementsID.begin();
4123 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4125 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4126 list<int>& listOfIDs = *arraysIt;
4127 aGroup.length( listOfIDs.size() );
4128 list<int>::iterator idIt = listOfIDs.begin();
4129 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4130 aGroup[ k ] = *idIt;
4133 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4137 SMESH_CATCH( SMESH::throwCorbaException );
4140 //=======================================================================
4141 //function : MergeElements
4143 //=======================================================================
4145 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4146 throw (SALOME::SALOME_Exception)
4151 TPythonDump aTPythonDump;
4152 aTPythonDump << this << ".MergeElements( [";
4154 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4156 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4157 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4158 aListOfListOfElementsID.push_back( list< int >() );
4159 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4160 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4161 CORBA::Long id = anElemsIDGroup[ j ];
4162 aListOfElemsID.push_back( id );
4164 if ( aListOfElemsID.size() < 2 )
4165 aListOfListOfElementsID.pop_back();
4166 if ( i > 0 ) aTPythonDump << ", ";
4167 aTPythonDump << anElemsIDGroup;
4170 getEditor().MergeElements(aListOfListOfElementsID);
4172 declareMeshModified( /*isReComputeSafe=*/true );
4174 aTPythonDump << "] )";
4176 SMESH_CATCH( SMESH::throwCorbaException );
4179 //=======================================================================
4180 //function : MergeEqualElements
4182 //=======================================================================
4184 void SMESH_MeshEditor_i::MergeEqualElements()
4185 throw (SALOME::SALOME_Exception)
4190 getEditor().MergeEqualElements();
4192 declareMeshModified( /*isReComputeSafe=*/true );
4194 TPythonDump() << this << ".MergeEqualElements()";
4196 SMESH_CATCH( SMESH::throwCorbaException );
4199 //=============================================================================
4201 * Move the node to a given point
4203 //=============================================================================
4205 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4209 throw (SALOME::SALOME_Exception)
4212 initData(/*deleteSearchers=*/false);
4214 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
4218 if ( theNodeSearcher )
4219 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4221 if ( myIsPreviewMode ) // make preview data
4223 // in a preview mesh, make edges linked to a node
4224 TPreviewMesh& tmpMesh = *getPreviewMesh();
4225 TIDSortedElemSet linkedNodes;
4226 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4227 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4228 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4229 for ( ; nIt != linkedNodes.end(); ++nIt )
4231 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4232 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4236 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4237 // fill preview data
4239 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4240 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4242 getMeshDS()->MoveNode(node, x, y, z);
4244 if ( !myIsPreviewMode )
4246 // Update Python script
4247 TPythonDump() << "isDone = " << this << ".MoveNode( "
4248 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
4249 declareMeshModified( /*isReComputeSafe=*/false );
4252 SMESH_CATCH( SMESH::throwCorbaException );
4257 //================================================================================
4259 * \brief Return ID of node closest to a given point
4261 //================================================================================
4263 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4266 throw (SALOME::SALOME_Exception)
4269 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4271 if ( !theNodeSearcher ) {
4272 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
4275 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4276 return node->GetID();
4278 SMESH_CATCH( SMESH::throwCorbaException );
4282 //================================================================================
4284 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4285 * move the node closest to the point to point's location and return ID of the node
4287 //================================================================================
4289 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4292 CORBA::Long theNodeID)
4293 throw (SALOME::SALOME_Exception)
4296 // We keep theNodeSearcher until any mesh modification:
4297 // 1) initData() deletes theNodeSearcher at any edition,
4298 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4300 initData(/*deleteSearchers=*/false);
4302 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4304 int nodeID = theNodeID;
4305 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
4306 if ( !node ) // preview moving node
4308 if ( !theNodeSearcher ) {
4309 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
4312 node = theNodeSearcher->FindClosestTo( p );
4315 nodeID = node->GetID();
4316 if ( myIsPreviewMode ) // make preview data
4318 // in a preview mesh, make edges linked to a node
4319 TPreviewMesh tmpMesh = *getPreviewMesh();
4320 TIDSortedElemSet linkedNodes;
4321 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4322 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4323 for ( ; nIt != linkedNodes.end(); ++nIt )
4325 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4326 tmpMesh.Copy( &edge );
4329 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4331 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4332 // fill preview data
4334 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4336 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4340 getMeshDS()->MoveNode(node, x, y, z);
4344 if ( !myIsPreviewMode )
4346 TPythonDump() << "nodeID = " << this
4347 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4348 << ", " << nodeID << " )";
4350 declareMeshModified( /*isReComputeSafe=*/false );
4355 SMESH_CATCH( SMESH::throwCorbaException );
4359 //=======================================================================
4361 * Return elements of given type where the given point is IN or ON.
4363 * 'ALL' type means elements of any type excluding nodes
4365 //=======================================================================
4367 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4370 SMESH::ElementType type)
4371 throw (SALOME::SALOME_Exception)
4374 SMESH::long_array_var res = new SMESH::long_array;
4375 vector< const SMDS_MeshElement* > foundElems;
4377 theSearchersDeleter.Set( myMesh );
4378 if ( !theElementSearcher ) {
4379 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
4381 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4382 SMDSAbs_ElementType( type ),
4384 res->length( foundElems.size() );
4385 for ( int i = 0; i < foundElems.size(); ++i )
4386 res[i] = foundElems[i]->GetID();
4390 SMESH_CATCH( SMESH::throwCorbaException );
4394 //=======================================================================
4395 //function : FindAmongElementsByPoint
4396 //purpose : Searching among the given elements, return elements of given type
4397 // where the given point is IN or ON.
4398 // 'ALL' type means elements of any type excluding nodes
4399 //=======================================================================
4402 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4406 SMESH::ElementType type)
4407 throw (SALOME::SALOME_Exception)
4410 SMESH::long_array_var res = new SMESH::long_array;
4412 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4413 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4414 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
4415 type != types[0] ) // but search of elements of dim > 0
4418 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4419 return FindElementsByPoint( x,y,z, type );
4421 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4423 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
4424 if ( !theElementSearcher )
4426 // create a searcher from elementIDs
4427 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4428 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4430 if ( !idSourceToSet( elementIDs, meshDS, elements,
4431 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
4434 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4435 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4437 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
4440 vector< const SMDS_MeshElement* > foundElems;
4442 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4443 SMDSAbs_ElementType( type ),
4445 res->length( foundElems.size() );
4446 for ( int i = 0; i < foundElems.size(); ++i )
4447 res[i] = foundElems[i]->GetID();
4451 SMESH_CATCH( SMESH::throwCorbaException );
4455 //=======================================================================
4456 //function : GetPointState
4457 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4458 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4459 //=======================================================================
4461 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4464 throw (SALOME::SALOME_Exception)
4467 theSearchersDeleter.Set( myMesh );
4468 if ( !theElementSearcher ) {
4469 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
4471 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4473 SMESH_CATCH( SMESH::throwCorbaException );
4477 //=======================================================================
4478 //function : convError
4480 //=======================================================================
4482 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4484 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4488 RETCASE( SEW_BORDER1_NOT_FOUND );
4489 RETCASE( SEW_BORDER2_NOT_FOUND );
4490 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4491 RETCASE( SEW_BAD_SIDE_NODES );
4492 RETCASE( SEW_VOLUMES_TO_SPLIT );
4493 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4494 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4495 RETCASE( SEW_BAD_SIDE1_NODES );
4496 RETCASE( SEW_BAD_SIDE2_NODES );
4498 return SMESH::SMESH_MeshEditor::SEW_OK;
4501 //=======================================================================
4502 //function : SewFreeBorders
4504 //=======================================================================
4506 SMESH::SMESH_MeshEditor::Sew_Error
4507 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4508 CORBA::Long SecondNodeID1,
4509 CORBA::Long LastNodeID1,
4510 CORBA::Long FirstNodeID2,
4511 CORBA::Long SecondNodeID2,
4512 CORBA::Long LastNodeID2,
4513 CORBA::Boolean CreatePolygons,
4514 CORBA::Boolean CreatePolyedrs)
4515 throw (SALOME::SALOME_Exception)
4520 SMESHDS_Mesh* aMesh = getMeshDS();
4522 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4523 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4524 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4525 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4526 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4527 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4529 if (!aBorderFirstNode ||
4530 !aBorderSecondNode||
4532 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4533 if (!aSide2FirstNode ||
4534 !aSide2SecondNode ||
4536 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4538 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4539 << FirstNodeID1 << ", "
4540 << SecondNodeID1 << ", "
4541 << LastNodeID1 << ", "
4542 << FirstNodeID2 << ", "
4543 << SecondNodeID2 << ", "
4544 << LastNodeID2 << ", "
4545 << CreatePolygons<< ", "
4546 << CreatePolyedrs<< " )";
4548 SMESH::SMESH_MeshEditor::Sew_Error error =
4549 convError( getEditor().SewFreeBorder (aBorderFirstNode,
4560 declareMeshModified( /*isReComputeSafe=*/false );
4563 SMESH_CATCH( SMESH::throwCorbaException );
4564 return SMESH::SMESH_MeshEditor::Sew_Error(0);
4568 //=======================================================================
4569 //function : SewConformFreeBorders
4571 //=======================================================================
4573 SMESH::SMESH_MeshEditor::Sew_Error
4574 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4575 CORBA::Long SecondNodeID1,
4576 CORBA::Long LastNodeID1,
4577 CORBA::Long FirstNodeID2,
4578 CORBA::Long SecondNodeID2)
4579 throw (SALOME::SALOME_Exception)
4584 SMESHDS_Mesh* aMesh = getMeshDS();
4586 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4587 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4588 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4589 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4590 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4591 const SMDS_MeshNode* aSide2ThirdNode = 0;
4593 if (!aBorderFirstNode ||
4594 !aBorderSecondNode||
4596 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4597 if (!aSide2FirstNode ||
4599 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4601 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
4602 << FirstNodeID1 << ", "
4603 << SecondNodeID1 << ", "
4604 << LastNodeID1 << ", "
4605 << FirstNodeID2 << ", "
4606 << SecondNodeID2 << " )";
4608 SMESH::SMESH_MeshEditor::Sew_Error error =
4609 convError( getEditor().SewFreeBorder (aBorderFirstNode,
4618 declareMeshModified( /*isReComputeSafe=*/false );
4621 SMESH_CATCH( SMESH::throwCorbaException );
4622 return SMESH::SMESH_MeshEditor::Sew_Error(0);
4626 //=======================================================================
4627 //function : SewBorderToSide
4629 //=======================================================================
4631 SMESH::SMESH_MeshEditor::Sew_Error
4632 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
4633 CORBA::Long SecondNodeIDOnFreeBorder,
4634 CORBA::Long LastNodeIDOnFreeBorder,
4635 CORBA::Long FirstNodeIDOnSide,
4636 CORBA::Long LastNodeIDOnSide,
4637 CORBA::Boolean CreatePolygons,
4638 CORBA::Boolean CreatePolyedrs)
4639 throw (SALOME::SALOME_Exception)
4644 SMESHDS_Mesh* aMesh = getMeshDS();
4646 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
4647 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
4648 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
4649 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
4650 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
4651 const SMDS_MeshNode* aSide2ThirdNode = 0;
4653 if (!aBorderFirstNode ||
4654 !aBorderSecondNode||
4656 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4657 if (!aSide2FirstNode ||
4659 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
4661 TPythonDump() << "error = " << this << ".SewBorderToSide( "
4662 << FirstNodeIDOnFreeBorder << ", "
4663 << SecondNodeIDOnFreeBorder << ", "
4664 << LastNodeIDOnFreeBorder << ", "
4665 << FirstNodeIDOnSide << ", "
4666 << LastNodeIDOnSide << ", "
4667 << CreatePolygons << ", "
4668 << CreatePolyedrs << ") ";
4670 SMESH::SMESH_MeshEditor::Sew_Error error =
4671 convError( getEditor().SewFreeBorder (aBorderFirstNode,
4681 declareMeshModified( /*isReComputeSafe=*/false );
4684 SMESH_CATCH( SMESH::throwCorbaException );
4685 return SMESH::SMESH_MeshEditor::Sew_Error(0);
4689 //=======================================================================
4690 //function : SewSideElements
4692 //=======================================================================
4694 SMESH::SMESH_MeshEditor::Sew_Error
4695 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
4696 const SMESH::long_array& IDsOfSide2Elements,
4697 CORBA::Long NodeID1OfSide1ToMerge,
4698 CORBA::Long NodeID1OfSide2ToMerge,
4699 CORBA::Long NodeID2OfSide1ToMerge,
4700 CORBA::Long NodeID2OfSide2ToMerge)
4701 throw (SALOME::SALOME_Exception)
4706 SMESHDS_Mesh* aMesh = getMeshDS();
4708 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
4709 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
4710 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
4711 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
4713 if (!aFirstNode1ToMerge ||
4714 !aFirstNode2ToMerge )
4715 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
4716 if (!aSecondNode1ToMerge||
4717 !aSecondNode2ToMerge)
4718 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
4720 TIDSortedElemSet aSide1Elems, aSide2Elems;
4721 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
4722 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
4724 TPythonDump() << "error = " << this << ".SewSideElements( "
4725 << IDsOfSide1Elements << ", "
4726 << IDsOfSide2Elements << ", "
4727 << NodeID1OfSide1ToMerge << ", "
4728 << NodeID1OfSide2ToMerge << ", "
4729 << NodeID2OfSide1ToMerge << ", "
4730 << NodeID2OfSide2ToMerge << ")";
4732 SMESH::SMESH_MeshEditor::Sew_Error error =
4733 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
4736 aSecondNode1ToMerge,
4737 aSecondNode2ToMerge));
4739 declareMeshModified( /*isReComputeSafe=*/false );
4742 SMESH_CATCH( SMESH::throwCorbaException );
4743 return SMESH::SMESH_MeshEditor::Sew_Error(0);
4746 //================================================================================
4748 * \brief Set new nodes for given element
4749 * \param ide - element id
4750 * \param newIDs - new node ids
4751 * \retval CORBA::Boolean - true if result is OK
4753 //================================================================================
4755 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
4756 const SMESH::long_array& newIDs)
4757 throw (SALOME::SALOME_Exception)
4762 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
4763 if(!elem) return false;
4765 int nbn = newIDs.length();
4767 vector<const SMDS_MeshNode*> aNodes(nbn);
4770 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
4773 aNodes[nbn1] = aNode;
4776 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
4777 << ide << ", " << newIDs << " )";
4779 MESSAGE("ChangeElementNodes");
4780 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
4782 declareMeshModified( /*isReComputeSafe=*/ !res );
4786 SMESH_CATCH( SMESH::throwCorbaException );
4790 //=======================================================================
4792 * \brief Makes a part of the mesh quadratic or bi-quadratic
4794 //=======================================================================
4796 void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d,
4797 CORBA::Boolean theToBiQuad,
4798 SMESH::SMESH_IDSource_ptr theObject)
4799 throw (SALOME::SALOME_Exception)
4804 TIDSortedElemSet elems;
4806 if ( !( elemsOK = CORBA::is_nil( theObject )))
4808 elemsOK = idSourceToSet( theObject, getMeshDS(), elems,
4809 SMDSAbs_All, /*emptyIfIsMesh=*/true );
4813 if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
4814 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
4816 if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
4817 else getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
4819 declareMeshModified( /*isReComputeSafe=*/false );
4822 SMESH_CATCH( SMESH::throwCorbaException );
4825 //=======================================================================
4826 //function : ConvertFromQuadratic
4828 //=======================================================================
4830 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
4831 throw (SALOME::SALOME_Exception)
4836 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
4837 TPythonDump() << this << ".ConvertFromQuadratic()";
4838 declareMeshModified( /*isReComputeSafe=*/!isDone );
4841 SMESH_CATCH( SMESH::throwCorbaException );
4845 //=======================================================================
4846 //function : ConvertToQuadratic
4848 //=======================================================================
4850 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
4851 throw (SALOME::SALOME_Exception)
4853 convertToQuadratic( theForce3d, false );
4854 TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
4857 //================================================================================
4859 * \brief Makes a part of the mesh quadratic
4861 //================================================================================
4863 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
4864 SMESH::SMESH_IDSource_ptr theObject)
4865 throw (SALOME::SALOME_Exception)
4867 convertToQuadratic( theForce3d, false, theObject );
4868 TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
4871 //================================================================================
4873 * \brief Makes a part of the mesh bi-quadratic
4875 //================================================================================
4877 void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean theForce3d,
4878 SMESH::SMESH_IDSource_ptr theObject)
4879 throw (SALOME::SALOME_Exception)
4881 convertToQuadratic( theForce3d, true, theObject );
4882 TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
4885 //================================================================================
4887 * \brief Makes a part of the mesh linear
4889 //================================================================================
4891 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
4892 throw (SALOME::SALOME_Exception)
4899 TIDSortedElemSet elems;
4900 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
4902 if ( elems.empty() )
4904 ConvertFromQuadratic();
4906 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
4908 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
4912 getEditor().ConvertFromQuadratic(elems);
4915 declareMeshModified( /*isReComputeSafe=*/false );
4917 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
4919 SMESH_CATCH( SMESH::throwCorbaException );
4922 //=======================================================================
4923 //function : makeMesh
4924 //purpose : create a named imported mesh
4925 //=======================================================================
4927 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
4929 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
4930 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
4931 SALOMEDS::Study_var study = gen->GetCurrentStudy();
4932 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
4933 gen->SetName( meshSO, theMeshName, "Mesh" );
4934 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
4936 return mesh._retn();
4939 //=======================================================================
4940 //function : dumpGroupsList
4942 //=======================================================================
4944 void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPython,
4945 const SMESH::ListOfGroups * theGroupList)
4947 bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
4948 if ( isDumpGroupList )
4949 theDumpPython << theGroupList << " = ";
4952 //================================================================================
4954 \brief Generates the unique group name.
4955 \param thePrefix name prefix
4958 //================================================================================
4960 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
4962 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
4963 set<string> groupNames;
4965 // Get existing group names
4966 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
4967 SMESH::SMESH_GroupBase_var aGroup = groups[i];
4968 if (CORBA::is_nil(aGroup))
4971 CORBA::String_var name = aGroup->GetName();
4972 groupNames.insert( name.in() );
4976 string name = thePrefix;
4979 while (!groupNames.insert(name).second)
4980 name = SMESH_Comment( thePrefix ) << "_" << index++;
4985 //================================================================================
4987 * \brief Prepare SMESH_IDSource for work
4989 //================================================================================
4991 void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
4993 if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
4995 SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
4996 filter->SetMesh( mesh );
4999 //================================================================================
5001 * \brief Retrieve elements of given type from SMESH_IDSource
5003 //================================================================================
5005 bool SMESH_MeshEditor_i::idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
5006 const SMESHDS_Mesh* theMeshDS,
5007 TIDSortedElemSet& theElemSet,
5008 const SMDSAbs_ElementType theType,
5009 const bool emptyIfIsMesh,
5010 IDSource_Error* error)
5013 if ( error ) *error = IDSource_OK;
5015 if ( CORBA::is_nil( theIDSource ) )
5017 if ( error ) *error = IDSource_INVALID;
5020 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
5022 if ( error && getMeshDS()->GetMeshInfo().NbElements( theType ) == 0 )
5023 *error = IDSource_EMPTY;
5026 prepareIdSource( theIDSource );
5027 SMESH::long_array_var anIDs = theIDSource->GetIDs();
5028 if ( anIDs->length() == 0 )
5030 if ( error ) *error = IDSource_EMPTY;
5033 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
5034 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5036 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
5038 arrayToSet( anIDs, getMeshDS(), theElemSet, SMDSAbs_Node );
5042 if ( error ) *error = IDSource_INVALID;
5048 arrayToSet( anIDs, getMeshDS(), theElemSet, theType);
5049 if ( bool(anIDs->length()) != bool(theElemSet.size()))
5051 if ( error ) *error = IDSource_INVALID;
5058 //================================================================================
5060 * \brief Duplicates given elements, i.e. creates new elements based on the
5061 * same nodes as the given ones.
5062 * \param theElements - container of elements to duplicate.
5063 * \param theGroupName - a name of group to contain the generated elements.
5064 * If a group with such a name already exists, the new elements
5065 * are added to the existng group, else a new group is created.
5066 * If \a theGroupName is empty, new elements are not added
5068 * \return a group where the new elements are added. NULL if theGroupName == "".
5071 //================================================================================
5073 SMESH::SMESH_Group_ptr
5074 SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
5075 const char* theGroupName)
5076 throw (SALOME::SALOME_Exception)
5078 SMESH::SMESH_Group_var newGroup;
5085 TIDSortedElemSet elems;
5086 if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
5088 getEditor().DoubleElements( elems );
5090 if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
5093 SMESH::ElementType type =
5094 SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
5095 // find existing group
5096 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5097 for ( size_t i = 0; i < groups->length(); ++i )
5098 if ( groups[i]->GetType() == type )
5100 CORBA::String_var name = groups[i]->GetName();
5101 if ( strcmp( name, theGroupName ) == 0 ) {
5102 newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
5106 // create a new group
5107 if ( newGroup->_is_nil() )
5108 newGroup = myMesh_i->CreateGroup( type, theGroupName );
5110 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
5112 SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
5113 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
5114 for ( int i = 1; i <= aSeq.Length(); i++ )
5115 groupDS->SMDSGroup().Add( aSeq(i) );
5120 if ( !newGroup->_is_nil() )
5121 pyDump << newGroup << " = ";
5122 pyDump << this << ".DoubleElements( "
5123 << theElements << ", " << "'" << theGroupName <<"')";
5125 SMESH_CATCH( SMESH::throwCorbaException );
5127 return newGroup._retn();
5130 //================================================================================
5132 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5133 \param theNodes - identifiers of nodes to be doubled
5134 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5135 nodes. If list of element identifiers is empty then nodes are doubled but
5136 they not assigned to elements
5137 \return TRUE if operation has been completed successfully, FALSE otherwise
5138 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5140 //================================================================================
5142 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5143 const SMESH::long_array& theModifiedElems )
5144 throw (SALOME::SALOME_Exception)
5149 list< int > aListOfNodes;
5151 for ( i = 0, n = theNodes.length(); i < n; i++ )
5152 aListOfNodes.push_back( theNodes[ i ] );
5154 list< int > aListOfElems;
5155 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5156 aListOfElems.push_back( theModifiedElems[ i ] );
5158 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
5160 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5162 // Update Python script
5163 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5167 SMESH_CATCH( SMESH::throwCorbaException );
5171 //================================================================================
5173 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5174 This method provided for convenience works as DoubleNodes() described above.
5175 \param theNodeId - identifier of node to be doubled.
5176 \param theModifiedElems - identifiers of elements to be updated.
5177 \return TRUE if operation has been completed successfully, FALSE otherwise
5178 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5180 //================================================================================
5182 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5183 const SMESH::long_array& theModifiedElems )
5184 throw (SALOME::SALOME_Exception)
5187 SMESH::long_array_var aNodes = new SMESH::long_array;
5188 aNodes->length( 1 );
5189 aNodes[ 0 ] = theNodeId;
5191 TPythonDump pyDump; // suppress dump by the next line
5193 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5195 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5199 SMESH_CATCH( SMESH::throwCorbaException );
5203 //================================================================================
5205 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5206 This method provided for convenience works as DoubleNodes() described above.
5207 \param theNodes - group of nodes to be doubled.
5208 \param theModifiedElems - group of elements to be updated.
5209 \return TRUE if operation has been completed successfully, FALSE otherwise
5210 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5212 //================================================================================
5214 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5215 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5216 throw (SALOME::SALOME_Exception)
5219 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5222 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5223 SMESH::long_array_var aModifiedElems;
5224 if ( !CORBA::is_nil( theModifiedElems ) )
5225 aModifiedElems = theModifiedElems->GetListOfID();
5228 aModifiedElems = new SMESH::long_array;
5229 aModifiedElems->length( 0 );
5232 TPythonDump pyDump; // suppress dump by the next line
5234 bool done = DoubleNodes( aNodes, aModifiedElems );
5236 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5240 SMESH_CATCH( SMESH::throwCorbaException );
5244 //================================================================================
5246 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5247 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5248 * \param theNodes - group of nodes to be doubled.
5249 * \param theModifiedElems - group of elements to be updated.
5250 * \return a new group with newly created nodes
5251 * \sa DoubleNodeGroup()
5253 //================================================================================
5255 SMESH::SMESH_Group_ptr
5256 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5257 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5258 throw (SALOME::SALOME_Exception)
5261 SMESH::SMESH_Group_var aNewGroup;
5263 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5264 return aNewGroup._retn();
5267 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5268 SMESH::long_array_var aModifiedElems;
5269 if ( !CORBA::is_nil( theModifiedElems ) )
5270 aModifiedElems = theModifiedElems->GetListOfID();
5272 aModifiedElems = new SMESH::long_array;
5273 aModifiedElems->length( 0 );
5276 TPythonDump pyDump; // suppress dump by the next line
5278 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5281 // Create group with newly created nodes
5282 SMESH::long_array_var anIds = GetLastCreatedNodes();
5283 if (anIds->length() > 0) {
5284 string anUnindexedName (theNodes->GetName());
5285 string aNewName = generateGroupName(anUnindexedName + "_double");
5286 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5287 aNewGroup->Add(anIds);
5288 pyDump << aNewGroup << " = ";
5292 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5293 << theModifiedElems << " )";
5295 return aNewGroup._retn();
5297 SMESH_CATCH( SMESH::throwCorbaException );
5301 //================================================================================
5303 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5304 This method provided for convenience works as DoubleNodes() described above.
5305 \param theNodes - list of groups of nodes to be doubled
5306 \param theModifiedElems - list of groups of elements to be updated.
5307 \return TRUE if operation has been completed successfully, FALSE otherwise
5308 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5310 //================================================================================
5312 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5313 const SMESH::ListOfGroups& theModifiedElems )
5314 throw (SALOME::SALOME_Exception)
5319 std::list< int > aNodes;
5321 for ( i = 0, n = theNodes.length(); i < n; i++ )
5323 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5324 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5326 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5327 for ( j = 0, m = aCurr->length(); j < m; j++ )
5328 aNodes.push_back( aCurr[ j ] );
5332 std::list< int > anElems;
5333 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5335 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5336 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5338 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5339 for ( j = 0, m = aCurr->length(); j < m; j++ )
5340 anElems.push_back( aCurr[ j ] );
5344 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
5346 declareMeshModified( /*isReComputeSafe=*/false );
5348 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5352 SMESH_CATCH( SMESH::throwCorbaException );
5356 //================================================================================
5358 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5359 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5360 * \param theNodes - group of nodes to be doubled.
5361 * \param theModifiedElems - group of elements to be updated.
5362 * \return a new group with newly created nodes
5363 * \sa DoubleNodeGroups()
5365 //================================================================================
5367 SMESH::SMESH_Group_ptr
5368 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5369 const SMESH::ListOfGroups& theModifiedElems )
5370 throw (SALOME::SALOME_Exception)
5372 SMESH::SMESH_Group_var aNewGroup;
5374 TPythonDump pyDump; // suppress dump by the next line
5376 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5380 // Create group with newly created nodes
5381 SMESH::long_array_var anIds = GetLastCreatedNodes();
5382 if (anIds->length() > 0) {
5383 string anUnindexedName (theNodes[0]->GetName());
5384 string aNewName = generateGroupName(anUnindexedName + "_double");
5385 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5386 aNewGroup->Add(anIds);
5387 pyDump << aNewGroup << " = ";
5391 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5392 << theModifiedElems << " )";
5394 return aNewGroup._retn();
5398 //================================================================================
5400 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5401 \param theElems - the list of elements (edges or faces) to be replicated
5402 The nodes for duplication could be found from these elements
5403 \param theNodesNot - list of nodes to NOT replicate
5404 \param theAffectedElems - the list of elements (cells and edges) to which the
5405 replicated nodes should be associated to.
5406 \return TRUE if operation has been completed successfully, FALSE otherwise
5407 \sa DoubleNodeGroup(), DoubleNodeGroups()
5409 //================================================================================
5411 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5412 const SMESH::long_array& theNodesNot,
5413 const SMESH::long_array& theAffectedElems )
5414 throw (SALOME::SALOME_Exception)
5419 SMESHDS_Mesh* aMeshDS = getMeshDS();
5420 TIDSortedElemSet anElems, aNodes, anAffected;
5421 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5422 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5423 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5425 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5427 // Update Python script
5428 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5429 << theNodesNot << ", " << theAffectedElems << " )";
5431 declareMeshModified( /*isReComputeSafe=*/false );
5434 SMESH_CATCH( SMESH::throwCorbaException );
5438 //================================================================================
5440 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5441 \param theElems - the list of elements (edges or faces) to be replicated
5442 The nodes for duplication could be found from these elements
5443 \param theNodesNot - list of nodes to NOT replicate
5444 \param theShape - shape to detect affected elements (element which geometric center
5445 located on or inside shape).
5446 The replicated nodes should be associated to affected elements.
5447 \return TRUE if operation has been completed successfully, FALSE otherwise
5448 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5450 //================================================================================
5452 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5453 const SMESH::long_array& theNodesNot,
5454 GEOM::GEOM_Object_ptr theShape )
5455 throw (SALOME::SALOME_Exception)
5461 SMESHDS_Mesh* aMeshDS = getMeshDS();
5462 TIDSortedElemSet anElems, aNodes;
5463 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5464 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5466 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5467 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
5469 // Update Python script
5470 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5471 << theNodesNot << ", " << theShape << " )";
5473 declareMeshModified( /*isReComputeSafe=*/false );
5476 SMESH_CATCH( SMESH::throwCorbaException );
5480 //================================================================================
5482 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5483 \param theElems - group of of elements (edges or faces) to be replicated
5484 \param theNodesNot - group of nodes not to replicated
5485 \param theAffectedElems - group of elements to which the replicated nodes
5486 should be associated to.
5487 \return TRUE if operation has been completed successfully, FALSE otherwise
5488 \sa DoubleNodes(), DoubleNodeGroups()
5490 //================================================================================
5493 SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5494 SMESH::SMESH_GroupBase_ptr theNodesNot,
5495 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5496 throw (SALOME::SALOME_Exception)
5499 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5505 SMESHDS_Mesh* aMeshDS = getMeshDS();
5506 TIDSortedElemSet anElems, aNodes, anAffected;
5507 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5508 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5509 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5511 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5513 // Update Python script
5514 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5515 << theNodesNot << ", " << theAffectedElems << " )";
5517 declareMeshModified( /*isReComputeSafe=*/false );
5520 SMESH_CATCH( SMESH::throwCorbaException );
5524 //================================================================================
5526 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5527 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5528 * \param theElems - group of of elements (edges or faces) to be replicated
5529 * \param theNodesNot - group of nodes not to replicated
5530 * \param theAffectedElems - group of elements to which the replicated nodes
5531 * should be associated to.
5532 * \return a new group with newly created elements
5533 * \sa DoubleNodeElemGroup()
5535 //================================================================================
5537 SMESH::SMESH_Group_ptr
5538 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5539 SMESH::SMESH_GroupBase_ptr theNodesNot,
5540 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5541 throw (SALOME::SALOME_Exception)
5544 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
5548 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5549 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5551 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
5553 << theNodesNot << ", "
5554 << theAffectedElems << " )";
5556 return elemGroup._retn();
5559 //================================================================================
5561 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5562 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5563 * \param theElems - group of of elements (edges or faces) to be replicated
5564 * \param theNodesNot - group of nodes not to replicated
5565 * \param theAffectedElems - group of elements to which the replicated nodes
5566 * should be associated to.
5567 * \return a new group with newly created elements
5568 * \sa DoubleNodeElemGroup()
5570 //================================================================================
5572 SMESH::ListOfGroups*
5573 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
5574 SMESH::SMESH_GroupBase_ptr theNodesNot,
5575 SMESH::SMESH_GroupBase_ptr theAffectedElems,
5576 CORBA::Boolean theElemGroupNeeded,
5577 CORBA::Boolean theNodeGroupNeeded)
5578 throw (SALOME::SALOME_Exception)
5581 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5582 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5583 aTwoGroups->length( 2 );
5585 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5586 return aTwoGroups._retn();
5591 SMESHDS_Mesh* aMeshDS = getMeshDS();
5592 TIDSortedElemSet anElems, aNodes, anAffected;
5593 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5594 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5595 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5598 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5600 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5606 // Create group with newly created elements
5607 CORBA::String_var elemGroupName = theElems->GetName();
5608 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5609 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5611 SMESH::long_array_var anIds = GetLastCreatedElems();
5612 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5613 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5614 aNewElemGroup->Add(anIds);
5616 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5618 SMESH::long_array_var anIds = GetLastCreatedNodes();
5619 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5620 aNewNodeGroup->Add(anIds);
5624 // Update Python script
5627 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5628 else pyDump << aNewElemGroup << ", ";
5629 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5630 else pyDump << aNewNodeGroup << " ] = ";
5632 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
5633 << theNodesNot << ", "
5634 << theAffectedElems << ", "
5635 << theElemGroupNeeded << ", "
5636 << theNodeGroupNeeded <<" )";
5638 aTwoGroups[0] = aNewElemGroup._retn();
5639 aTwoGroups[1] = aNewNodeGroup._retn();
5640 return aTwoGroups._retn();
5642 SMESH_CATCH( SMESH::throwCorbaException );
5646 //================================================================================
5648 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5649 \param theElems - group of of elements (edges or faces) to be replicated
5650 \param theNodesNot - group of nodes not to replicated
5651 \param theShape - shape to detect affected elements (element which geometric center
5652 located on or inside shape).
5653 The replicated nodes should be associated to affected elements.
5654 \return TRUE if operation has been completed successfully, FALSE otherwise
5655 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5657 //================================================================================
5660 SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5661 SMESH::SMESH_GroupBase_ptr theNodesNot,
5662 GEOM::GEOM_Object_ptr theShape )
5663 throw (SALOME::SALOME_Exception)
5666 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5672 SMESHDS_Mesh* aMeshDS = getMeshDS();
5673 TIDSortedElemSet anElems, aNodes, anAffected;
5674 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5675 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5677 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5678 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
5681 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5683 // Update Python script
5684 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5685 << theNodesNot << ", " << theShape << " )";
5688 SMESH_CATCH( SMESH::throwCorbaException );
5692 //================================================================================
5694 * \brief Re-load elements from a list of groups into a TIDSortedElemSet
5695 * \param [in] theGrpList - groups
5696 * \param [in] theMeshDS - mesh
5697 * \param [out] theElemSet - set of elements
5698 * \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
5700 //================================================================================
5702 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5703 SMESHDS_Mesh* theMeshDS,
5704 TIDSortedElemSet& theElemSet,
5705 const bool theIsNodeGrp)
5707 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
5709 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
5710 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
5711 : aGrp->GetType() != SMESH::NODE ) )
5713 SMESH::long_array_var anIDs = aGrp->GetIDs();
5714 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
5719 //================================================================================
5721 \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5722 This method provided for convenience works as DoubleNodes() described above.
5723 \param theElems - list of groups of elements (edges or faces) to be replicated
5724 \param theNodesNot - list of groups of nodes not to replicated
5725 \param theAffectedElems - group of elements to which the replicated nodes
5726 should be associated to.
5727 \return TRUE if operation has been completed successfully, FALSE otherwise
5728 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
5730 //================================================================================
5733 SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
5734 const SMESH::ListOfGroups& theNodesNot,
5735 const SMESH::ListOfGroups& theAffectedElems)
5736 throw (SALOME::SALOME_Exception)
5742 SMESHDS_Mesh* aMeshDS = getMeshDS();
5743 TIDSortedElemSet anElems, aNodes, anAffected;
5744 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5745 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5746 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5748 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5750 // Update Python script
5751 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
5752 << &theNodesNot << ", " << &theAffectedElems << " )";
5754 declareMeshModified( /*isReComputeSafe=*/false );
5757 SMESH_CATCH( SMESH::throwCorbaException );
5761 //================================================================================
5763 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5764 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
5765 \param theElems - list of groups of elements (edges or faces) to be replicated
5766 \param theNodesNot - list of groups of nodes not to replicated
5767 \param theAffectedElems - group of elements to which the replicated nodes
5768 should be associated to.
5769 * \return a new group with newly created elements
5770 * \sa DoubleNodeElemGroups()
5772 //================================================================================
5774 SMESH::SMESH_Group_ptr
5775 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
5776 const SMESH::ListOfGroups& theNodesNot,
5777 const SMESH::ListOfGroups& theAffectedElems)
5778 throw (SALOME::SALOME_Exception)
5781 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
5785 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5786 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5788 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
5790 << theNodesNot << ", "
5791 << theAffectedElems << " )";
5793 return elemGroup._retn();
5796 //================================================================================
5798 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5799 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
5800 \param theElems - list of groups of elements (edges or faces) to be replicated
5801 \param theNodesNot - list of groups of nodes not to replicated
5802 \param theAffectedElems - group of elements to which the replicated nodes
5803 should be associated to.
5804 * \return a new group with newly created elements
5805 * \sa DoubleNodeElemGroups()
5807 //================================================================================
5809 SMESH::ListOfGroups*
5810 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
5811 const SMESH::ListOfGroups& theNodesNot,
5812 const SMESH::ListOfGroups& theAffectedElems,
5813 CORBA::Boolean theElemGroupNeeded,
5814 CORBA::Boolean theNodeGroupNeeded)
5815 throw (SALOME::SALOME_Exception)
5818 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5819 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5820 aTwoGroups->length( 2 );
5825 SMESHDS_Mesh* aMeshDS = getMeshDS();
5826 TIDSortedElemSet anElems, aNodes, anAffected;
5827 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5828 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5829 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5831 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5833 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5838 // Create group with newly created elements
5839 CORBA::String_var elemGroupName = theElems[0]->GetName();
5840 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5841 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5843 SMESH::long_array_var anIds = GetLastCreatedElems();
5844 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5845 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5846 aNewElemGroup->Add(anIds);
5848 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5850 SMESH::long_array_var anIds = GetLastCreatedNodes();
5851 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5852 aNewNodeGroup->Add(anIds);
5856 // Update Python script
5859 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5860 else pyDump << aNewElemGroup << ", ";
5861 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5862 else pyDump << aNewNodeGroup << " ] = ";
5864 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
5865 << &theNodesNot << ", "
5866 << &theAffectedElems << ", "
5867 << theElemGroupNeeded << ", "
5868 << theNodeGroupNeeded << " )";
5870 aTwoGroups[0] = aNewElemGroup._retn();
5871 aTwoGroups[1] = aNewNodeGroup._retn();
5872 return aTwoGroups._retn();
5874 SMESH_CATCH( SMESH::throwCorbaException );
5878 //================================================================================
5880 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5881 This method provided for convenience works as DoubleNodes() described above.
5882 \param theElems - list of groups of elements (edges or faces) to be replicated
5883 \param theNodesNot - list of groups of nodes not to replicated
5884 \param theShape - shape to detect affected elements (element which geometric center
5885 located on or inside shape).
5886 The replicated nodes should be associated to affected elements.
5887 \return TRUE if operation has been completed successfully, FALSE otherwise
5888 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
5890 //================================================================================
5893 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
5894 const SMESH::ListOfGroups& theNodesNot,
5895 GEOM::GEOM_Object_ptr theShape )
5896 throw (SALOME::SALOME_Exception)
5902 SMESHDS_Mesh* aMeshDS = getMeshDS();
5903 TIDSortedElemSet anElems, aNodes;
5904 listOfGroupToSet(theElems, aMeshDS, anElems,false );
5905 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5907 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5908 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
5910 // Update Python script
5911 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
5912 << &theNodesNot << ", " << theShape << " )";
5914 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5917 SMESH_CATCH( SMESH::throwCorbaException );
5921 //================================================================================
5923 \brief Identify the elements that will be affected by node duplication (actual
5924 duplication is not performed.
5925 This method is the first step of DoubleNodeElemGroupsInRegion.
5926 \param theElems - list of groups of elements (edges or faces) to be replicated
5927 \param theNodesNot - list of groups of nodes not to replicated
5928 \param theShape - shape to detect affected elements (element which geometric center
5929 located on or inside shape).
5930 The replicated nodes should be associated to affected elements.
5931 \return groups of affected elements
5932 \sa DoubleNodeElemGroupsInRegion()
5934 //================================================================================
5935 SMESH::ListOfGroups*
5936 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
5937 const SMESH::ListOfGroups& theNodesNot,
5938 GEOM::GEOM_Object_ptr theShape )
5939 throw (SALOME::SALOME_Exception)
5942 MESSAGE("AffectedElemGroupsInRegion");
5943 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
5944 bool isEdgeGroup = false;
5945 bool isFaceGroup = false;
5946 bool isVolumeGroup = false;
5947 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
5948 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
5949 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
5953 ::SMESH_MeshEditor aMeshEditor(myMesh);
5955 SMESHDS_Mesh* aMeshDS = getMeshDS();
5956 TIDSortedElemSet anElems, aNodes;
5957 listOfGroupToSet(theElems, aMeshDS, anElems, false);
5958 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
5960 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
5961 TIDSortedElemSet anAffected;
5962 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
5965 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5970 int lg = anAffected.size();
5971 MESSAGE("lg="<< lg);
5972 SMESH::long_array_var volumeIds = new SMESH::long_array;
5973 volumeIds->length(lg);
5974 SMESH::long_array_var faceIds = new SMESH::long_array;
5975 faceIds->length(lg);
5976 SMESH::long_array_var edgeIds = new SMESH::long_array;
5977 edgeIds->length(lg);
5982 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
5983 for (; eIt != anAffected.end(); ++eIt)
5985 const SMDS_MeshElement* anElem = *eIt;
5988 int elemId = anElem->GetID();
5989 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
5990 volumeIds[ivol++] = elemId;
5991 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
5992 faceIds[iface++] = elemId;
5993 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
5994 edgeIds[iedge++] = elemId;
5996 volumeIds->length(ivol);
5997 faceIds->length(iface);
5998 edgeIds->length(iedge);
6000 aNewVolumeGroup->Add(volumeIds);
6001 aNewFaceGroup->Add(faceIds);
6002 aNewEdgeGroup->Add(edgeIds);
6003 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6004 isFaceGroup = (aNewFaceGroup->Size() > 0);
6005 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6009 if (isEdgeGroup) nbGroups++;
6010 if (isFaceGroup) nbGroups++;
6011 if (isVolumeGroup) nbGroups++;
6012 aListOfGroups->length(nbGroups);
6015 if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
6016 if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
6017 if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
6019 // Update Python script
6022 if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
6023 if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
6024 if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
6026 pyDump << this << ".AffectedElemGroupsInRegion( "
6027 << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6029 return aListOfGroups._retn();
6031 SMESH_CATCH( SMESH::throwCorbaException );
6035 //================================================================================
6037 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6038 The created 2D mesh elements based on nodes of free faces of boundary volumes
6039 \return TRUE if operation has been completed successfully, FALSE otherwise
6041 //================================================================================
6043 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6044 throw (SALOME::SALOME_Exception)
6049 bool aResult = getEditor().Make2DMeshFrom3D();
6051 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6053 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6056 SMESH_CATCH( SMESH::throwCorbaException );
6060 //================================================================================
6062 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6063 * The list of groups must contain at least two groups. The groups have to be disjoint:
6064 * no common element into two different groups.
6065 * The nodes of the internal faces at the boundaries of the groups are doubled.
6066 * Optionally, the internal faces are replaced by flat elements.
6067 * Triangles are transformed into prisms, and quadrangles into hexahedrons.
6068 * The flat elements are stored in groups of volumes.
6069 * These groups are named according to the position of the group in the list:
6070 * the group j_n_p is the group of the flat elements that are built between the group #n and the group #p in the list.
6071 * 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.
6072 * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
6073 * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
6074 * \param theDomains - list of groups of volumes
6075 * \param createJointElems - if TRUE, create the elements
6076 * \param onAllBoundaries - if TRUE, the nodes and elements are also created on
6077 * the boundary between \a theDomains and the rest mesh
6078 * \return TRUE if operation has been completed successfully, FALSE otherwise
6080 //================================================================================
6083 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6084 CORBA::Boolean createJointElems,
6085 CORBA::Boolean onAllBoundaries )
6086 throw (SALOME::SALOME_Exception)
6093 SMESHDS_Mesh* aMeshDS = getMeshDS();
6095 // MESSAGE("theDomains.length = "<<theDomains.length());
6096 if ( theDomains.length() <= 1 && !onAllBoundaries )
6097 THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
6099 vector<TIDSortedElemSet> domains;
6100 domains.resize( theDomains.length() );
6102 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6104 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6105 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6107 // if ( aGrp->GetType() != SMESH::VOLUME )
6108 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6109 SMESH::long_array_var anIDs = aGrp->GetIDs();
6110 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6114 isOK = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems, onAllBoundaries );
6115 // TODO publish the groups of flat elements in study
6117 declareMeshModified( /*isReComputeSafe=*/ !isOK );
6119 // Update Python script
6120 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6121 << ", " << createJointElems << ", " << onAllBoundaries << " )";
6123 SMESH_CATCH( SMESH::throwCorbaException );
6125 myMesh_i->CreateGroupServants(); // publish created groups if any
6130 //================================================================================
6132 * \brief Double nodes on some external faces and create flat elements.
6133 * Flat elements are mainly used by some types of mechanic calculations.
6135 * Each group of the list must be constituted of faces.
6136 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6137 * @param theGroupsOfFaces - list of groups of faces
6138 * @return TRUE if operation has been completed successfully, FALSE otherwise
6140 //================================================================================
6143 SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6144 throw (SALOME::SALOME_Exception)
6149 SMESHDS_Mesh* aMeshDS = getMeshDS();
6151 vector<TIDSortedElemSet> faceGroups;
6154 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6156 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6157 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6159 TIDSortedElemSet faceGroup;
6161 faceGroups.push_back(faceGroup);
6162 SMESH::long_array_var anIDs = aGrp->GetIDs();
6163 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6167 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
6168 // TODO publish the groups of flat elements in study
6170 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6172 // Update Python script
6173 TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6176 SMESH_CATCH( SMESH::throwCorbaException );
6180 //================================================================================
6182 * \brief Identify all the elements around a geom shape, get the faces delimiting
6185 * Build groups of volume to remove, groups of faces to replace on the skin of the
6186 * object, groups of faces to remove inside the object, (idem edges).
6187 * Build ordered list of nodes at the border of each group of faces to replace
6188 * (to be used to build a geom subshape).
6190 //================================================================================
6192 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6193 GEOM::GEOM_Object_ptr theShape,
6194 const char* groupName,
6195 const SMESH::double_array& theNodesCoords,
6196 SMESH::array_of_long_array_out GroupsOfNodes)
6197 throw (SALOME::SALOME_Exception)
6202 std::vector<std::vector<int> > aListOfListOfNodes;
6203 ::SMESH_MeshEditor aMeshEditor( myMesh );
6205 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
6206 if ( !theNodeSearcher )
6207 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
6209 vector<double> nodesCoords;
6210 for (int i = 0; i < theNodesCoords.length(); i++)
6212 nodesCoords.push_back( theNodesCoords[i] );
6215 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6216 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
6217 nodesCoords, aListOfListOfNodes);
6219 GroupsOfNodes = new SMESH::array_of_long_array;
6220 GroupsOfNodes->length( aListOfListOfNodes.size() );
6221 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
6222 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
6224 vector<int>& aListOfNodes = *llIt;
6225 vector<int>::iterator lIt = aListOfNodes.begin();;
6226 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
6227 aGroup.length( aListOfNodes.size() );
6228 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
6229 aGroup[ j ] = (*lIt);
6231 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
6234 << ", '" << groupName << "', "
6235 << theNodesCoords << " )";
6237 SMESH_CATCH( SMESH::throwCorbaException );
6240 // issue 20749 ===================================================================
6242 * \brief Creates missing boundary elements
6243 * \param elements - elements whose boundary is to be checked
6244 * \param dimension - defines type of boundary elements to create
6245 * \param groupName - a name of group to store created boundary elements in,
6246 * "" means not to create the group
6247 * \param meshName - a name of new mesh to store created boundary elements in,
6248 * "" means not to create the new mesh
6249 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
6250 * \param toCopyExistingBondary - if true, not only new but also pre-existing
6251 * boundary elements will be copied into the new mesh
6252 * \param group - returns the create group, if any
6253 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
6255 // ================================================================================
6257 SMESH::SMESH_Mesh_ptr
6258 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
6259 SMESH::Bnd_Dimension dim,
6260 const char* groupName,
6261 const char* meshName,
6262 CORBA::Boolean toCopyElements,
6263 CORBA::Boolean toCopyExistingBondary,
6264 SMESH::SMESH_Group_out group)
6265 throw (SALOME::SALOME_Exception)
6270 if ( dim > SMESH::BND_1DFROM2D )
6271 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6273 SMESHDS_Mesh* aMeshDS = getMeshDS();
6275 SMESH::SMESH_Mesh_var mesh_var;
6276 SMESH::SMESH_Group_var group_var;
6280 TIDSortedElemSet elements;
6281 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
6282 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
6286 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
6287 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6289 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
6291 // group of new boundary elements
6292 SMESH_Group* smesh_group = 0;
6293 if ( strlen(groupName) )
6295 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
6296 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6297 smesh_group = group_i->GetSmeshGroup();
6301 getEditor().MakeBoundaryMesh( elements,
6302 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6306 toCopyExistingBondary);
6309 smesh_mesh->GetMeshDS()->Modified();
6312 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6314 // result of MakeBoundaryMesh() is a tuple (mesh, group)
6315 if ( mesh_var->_is_nil() )
6316 pyDump << myMesh_i->_this() << ", ";
6318 pyDump << mesh_var << ", ";
6319 if ( group_var->_is_nil() )
6320 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6322 pyDump << group_var << " = ";
6323 pyDump << this << ".MakeBoundaryMesh( "
6325 << "SMESH." << dimName[int(dim)] << ", "
6326 << "'" << groupName << "', "
6327 << "'" << meshName<< "', "
6328 << toCopyElements << ", "
6329 << toCopyExistingBondary << ")";
6331 group = group_var._retn();
6332 return mesh_var._retn();
6334 SMESH_CATCH( SMESH::throwCorbaException );
6335 return SMESH::SMESH_Mesh::_nil();
6338 //================================================================================
6340 * \brief Creates missing boundary elements
6341 * \param dimension - defines type of boundary elements to create
6342 * \param groupName - a name of group to store all boundary elements in,
6343 * "" means not to create the group
6344 * \param meshName - a name of a new mesh, which is a copy of the initial
6345 * mesh + created boundary elements; "" means not to create the new mesh
6346 * \param toCopyAll - if true, the whole initial mesh will be copied into
6347 * the new mesh else only boundary elements will be copied into the new mesh
6348 * \param groups - optional groups of elements to make boundary around
6349 * \param mesh - returns the mesh where elements were added to
6350 * \param group - returns the created group, if any
6351 * \retval long - number of added boundary elements
6353 //================================================================================
6355 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
6356 const char* groupName,
6357 const char* meshName,
6358 CORBA::Boolean toCopyAll,
6359 const SMESH::ListOfIDSources& groups,
6360 SMESH::SMESH_Mesh_out mesh,
6361 SMESH::SMESH_Group_out group)
6362 throw (SALOME::SALOME_Exception)
6367 if ( dim > SMESH::BND_1DFROM2D )
6368 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6370 // separate groups belonging to this and other mesh
6371 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
6372 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
6373 groupsOfThisMesh->length( groups.length() );
6374 groupsOfOtherMesh->length( groups.length() );
6375 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
6376 for ( int i = 0; i < groups.length(); ++i )
6378 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
6379 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
6380 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
6382 groupsOfThisMesh[ nbGroups++ ] = groups[i];
6383 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
6384 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
6386 groupsOfThisMesh->length( nbGroups );
6387 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
6392 if ( nbGroupsOfOtherMesh > 0 )
6394 // process groups belonging to another mesh
6395 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
6396 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
6397 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
6398 groupsOfOtherMesh, mesh, group );
6401 SMESH::SMESH_Mesh_var mesh_var;
6402 SMESH::SMESH_Group_var group_var;
6405 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
6406 const bool toCopyMesh = ( strlen( meshName ) > 0 );
6410 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
6412 /*toCopyGroups=*/false,
6413 /*toKeepIDs=*/true);
6415 mesh_var = makeMesh(meshName);
6417 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6418 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
6421 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
6422 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
6424 // group of boundary elements
6425 SMESH_Group* smesh_group = 0;
6426 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
6427 if ( strlen(groupName) )
6429 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
6430 group_var = mesh_i->CreateGroup( groupType, groupName );
6431 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6432 smesh_group = group_i->GetSmeshGroup();
6435 TIDSortedElemSet elements;
6437 if ( groups.length() > 0 )
6439 for ( int i = 0; i < nbGroups; ++i )
6442 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
6444 SMESH::Bnd_Dimension bdim =
6445 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
6446 nbAdded += getEditor().MakeBoundaryMesh( elements,
6447 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
6450 /*toCopyElements=*/false,
6451 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6452 /*toAddExistingBondary=*/true,
6453 /*aroundElements=*/true);
6459 nbAdded += getEditor().MakeBoundaryMesh( elements,
6460 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6463 /*toCopyElements=*/false,
6464 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6465 /*toAddExistingBondary=*/true);
6467 tgtMesh->GetMeshDS()->Modified();
6469 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6471 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
6472 pyDump << "nbAdded, ";
6473 if ( mesh_var->_is_nil() )
6474 pyDump << myMesh_i->_this() << ", ";
6476 pyDump << mesh_var << ", ";
6477 if ( group_var->_is_nil() )
6478 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6480 pyDump << group_var << " = ";
6481 pyDump << this << ".MakeBoundaryElements( "
6482 << "SMESH." << dimName[int(dim)] << ", "
6483 << "'" << groupName << "', "
6484 << "'" << meshName<< "', "
6485 << toCopyAll << ", "
6488 mesh = mesh_var._retn();
6489 group = group_var._retn();
6492 SMESH_CATCH( SMESH::throwCorbaException );