1 // Copyright (C) 2007-2013 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.
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>
68 #include <BRepAdaptor_Surface.hxx>
69 #include <BRep_Tool.hxx>
70 #include <TopExp_Explorer.hxx>
72 #include <TopoDS_Edge.hxx>
73 #include <TopoDS_Face.hxx>
78 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
82 #include <Standard_Failure.hxx>
85 #include <Standard_ErrorHandler.hxx>
91 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
93 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
96 using SMESH::TPythonDump;
99 namespace MeshEditor_I {
101 //=============================================================================
103 * \brief Mesh to apply modifications for preview purposes
105 //=============================================================================
107 struct TPreviewMesh: public SMESH_Mesh
109 SMDSAbs_ElementType myPreviewType; // type to show
111 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
112 _isShapeToMesh = (_id =_studyId = 0);
113 _myMeshDS = new SMESHDS_Mesh( _id, true );
114 myPreviewType = previewElements;
117 virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
118 //!< Copy a set of elements
119 void Copy(const TIDSortedElemSet & theElements,
120 TIDSortedElemSet& theCopyElements,
121 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
122 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
124 // loop on theIDsOfElements
125 TIDSortedElemSet::const_iterator eIt = theElements.begin();
126 for ( ; eIt != theElements.end(); ++eIt )
128 const SMDS_MeshElement* anElem = *eIt;
129 if ( !anElem ) continue;
130 SMDSAbs_ElementType type = anElem->GetType();
131 if ( type == theAvoidType ||
132 ( theSelectType != SMDSAbs_All && type != theSelectType ))
134 const SMDS_MeshElement* anElemCopy;
135 if ( type == SMDSAbs_Node)
136 anElemCopy = Copy( cast2Node(anElem) );
138 anElemCopy = Copy( anElem );
140 theCopyElements.insert( theCopyElements.end(), anElemCopy );
144 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
146 // copy element nodes
147 int anElemNbNodes = anElem->NbNodes();
148 vector< int > anElemNodesID( anElemNbNodes ) ;
149 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
150 for ( int i = 0; itElemNodes->more(); i++)
152 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
154 anElemNodesID[i] = anElemNode->GetID();
157 // creates a corresponding element on copied nodes
158 SMDS_MeshElement* anElemCopy = 0;
159 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
161 const SMDS_VtkVolume* ph =
162 dynamic_cast<const SMDS_VtkVolume*> (anElem);
164 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
165 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
168 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
175 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
177 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
178 anElemNode->GetID());
182 GetMeshDS()->ClearMesh();
184 };// struct TPreviewMesh
186 static SMESH_NodeSearcher * theNodeSearcher = 0;
187 static SMESH_ElementSearcher * theElementSearcher = 0;
189 //=============================================================================
191 * \brief Deleter of theNodeSearcher at any compute event occured
193 //=============================================================================
195 struct TSearchersDeleter : public SMESH_subMeshEventListener
198 string myMeshPartIOR;
200 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
201 "SMESH_MeshEditor_i::TSearchersDeleter"),
203 //!< Delete theNodeSearcher
206 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
207 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
209 typedef map < int, SMESH_subMesh * > TDependsOnMap;
210 //!< The meshod called by submesh: do my main job
211 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
212 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
214 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
216 Unset( sm->GetFather() );
219 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
220 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
222 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
229 myMeshPartIOR = meshPartIOR;
230 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
231 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
232 TDependsOnMap::const_iterator sm;
233 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
234 sm->second->SetEventListener( this, 0, sm->second );
238 //!< delete self from all submeshes
239 void Unset(SMESH_Mesh* mesh)
241 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
242 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
243 TDependsOnMap::const_iterator sm;
244 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
245 sm->second->DeleteEventListener( this );
250 } theSearchersDeleter;
252 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
254 TCollection_AsciiString typeStr;
255 switch ( theMirrorType ) {
256 case SMESH::SMESH_MeshEditor::POINT:
257 typeStr = "SMESH.SMESH_MeshEditor.POINT";
259 case SMESH::SMESH_MeshEditor::AXIS:
260 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
263 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
267 //================================================================================
269 * \brief function for conversion of long_array to TIDSortedElemSet
270 * \param IDs - array of IDs
271 * \param aMesh - mesh
272 * \param aMap - collection to fill
273 * \param aType - element type
275 //================================================================================
277 void arrayToSet(const SMESH::long_array & IDs,
278 const SMESHDS_Mesh* aMesh,
279 TIDSortedElemSet& aMap,
280 const SMDSAbs_ElementType aType = SMDSAbs_All )
282 SMDS_MeshElement::NonNullFilter filter1;
283 SMDS_MeshElement::TypeFilter filter2( aType );
284 SMDS_MeshElement::Filter & filter =
285 ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter&) filter1 : filter2;
287 if ( aType == SMDSAbs_Node )
288 for (int i=0; i<IDs.length(); i++) {
289 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
291 aMap.insert( aMap.end(), elem );
294 for (int i=0; i<IDs.length(); i++) {
295 const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
297 aMap.insert( aMap.end(), elem );
300 //================================================================================
302 * \brief Retrieve elements of given type from SMESH_IDSource
304 //================================================================================
306 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
307 const SMESHDS_Mesh* theMeshDS,
308 TIDSortedElemSet& theElemSet,
309 const SMDSAbs_ElementType theType,
310 const bool emptyIfIsMesh=false)
313 if ( CORBA::is_nil( theIDSource ) )
315 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
318 SMESH::long_array_var anIDs = theIDSource->GetIDs();
319 if ( anIDs->length() == 0 )
321 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
322 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
324 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
325 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
331 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
332 return bool(anIDs->length()) == bool(theElemSet.size());
336 //================================================================================
338 * \brief Retrieve nodes from SMESH_IDSource
340 //================================================================================
342 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
343 const SMESHDS_Mesh* theMeshDS,
344 TIDSortedNodeSet& theNodeSet)
347 if ( CORBA::is_nil( theObject ) )
349 SMESH::array_of_ElementType_var types = theObject->GetTypes();
350 SMESH::long_array_var aElementsId = theObject->GetIDs();
351 if ( types->length() == 1 && types[0] == SMESH::NODE)
353 for(int i = 0; i < aElementsId->length(); i++)
354 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
355 theNodeSet.insert( theNodeSet.end(), n);
357 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
359 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
360 while ( nIt->more( ))
361 if( const SMDS_MeshElement * elem = nIt->next() )
362 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
366 for(int i = 0; i < aElementsId->length(); i++)
367 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
368 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
372 //================================================================================
374 * \brief Returns elements connected to the given elements
376 //================================================================================
378 void getElementsAround(const TIDSortedElemSet& theElements,
379 const SMESHDS_Mesh* theMeshDS,
380 TIDSortedElemSet& theElementsAround)
382 if ( theElements.empty() ) return;
384 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
385 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
387 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
388 return; // all the elements are in theElements
391 elemType = SMDSAbs_All;
393 TIDSortedElemSet visitedNodes;
394 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
395 for ( ; elemIt != theElements.end(); ++elemIt )
397 const SMDS_MeshElement* e = *elemIt;
398 int i = e->NbCornerNodes();
401 const SMDS_MeshNode* n = e->GetNode( i );
402 if ( visitedNodes.insert( n ).second )
404 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
405 while ( invIt->more() )
407 const SMDS_MeshElement* elemAround = invIt->next();
408 if ( !theElements.count( elemAround ))
409 theElementsAround.insert( elemAround );
416 //================================================================================
418 * \brief Return a string used to detect change of mesh part on which theElementSearcher
419 * is going to be used
421 //================================================================================
423 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
425 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
426 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
427 // take into account passible group modification
428 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
429 partIOR += SMESH_Comment( type );
433 } // namespace MeshEditor_I
435 using namespace MeshEditor_I;
437 //=============================================================================
441 //=============================================================================
443 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
445 myMesh( &theMesh->GetImpl() ),
447 myIsPreviewMode ( isPreview ),
453 //================================================================================
457 //================================================================================
459 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
461 PortableServer::POA_var poa = SMESH_Gen_i::GetPOA();
462 PortableServer::ObjectId_var anObjectId = poa->servant_to_id(this);
463 poa->deactivate_object(anObjectId.in());
465 //deleteAuxIDSources();
466 delete myPreviewMesh; myPreviewMesh = 0;
467 delete myPreviewEditor; myPreviewEditor = 0;
470 //================================================================================
472 * \brief Clear members
474 //================================================================================
476 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
478 if ( myIsPreviewMode ) {
479 if ( myPreviewMesh ) myPreviewMesh->RemoveAll();
482 if ( deleteSearchers )
483 TSearchersDeleter::Delete();
485 getEditor().GetError().reset();
486 getEditor().CrearLastCreated();
489 //================================================================================
491 * \brief Increment mesh modif time and optionally record that the performed
492 * modification may influence futher mesh re-compute.
493 * \param [in] isReComputeSafe - true if the modification does not infulence
494 * futher mesh re-compute
496 //================================================================================
498 void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
500 myMesh->GetMeshDS()->Modified();
501 if ( !isReComputeSafe )
502 myMesh->SetIsModified( true );
505 //================================================================================
507 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
508 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
510 //================================================================================
512 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
514 if ( myIsPreviewMode && !myPreviewEditor ) {
515 if ( !myPreviewMesh ) getPreviewMesh();
516 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
518 return myIsPreviewMode ? *myPreviewEditor : myEditor;
521 //================================================================================
523 * \brief Initialize and return myPreviewMesh
524 * \param previewElements - type of elements to show in preview
526 * WARNING: call it once par a method!
528 //================================================================================
530 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
532 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
534 delete myPreviewEditor;
536 delete myPreviewMesh;
537 myPreviewMesh = new TPreviewMesh( previewElements );
539 myPreviewMesh->Clear();
540 return myPreviewMesh;
543 //================================================================================
545 * Return data of mesh edition preview
547 //================================================================================
549 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
550 throw (SALOME::SALOME_Exception)
553 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
555 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
557 list<int> aNodesConnectivity;
558 typedef map<int, int> TNodesMap;
561 SMESHDS_Mesh* aMeshDS;
562 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
564 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
565 aMeshDS = aMeshPartDS.get();
568 aMeshDS = getEditor().GetMeshDS();
570 myPreviewData = new SMESH::MeshPreviewStruct();
571 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
574 SMDSAbs_ElementType previewType = SMDSAbs_All;
576 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
577 previewType = aPreviewMesh->myPreviewType;
578 switch ( previewType ) {
579 case SMDSAbs_Edge : break;
580 case SMDSAbs_Face : break;
581 case SMDSAbs_Volume: break;
583 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
587 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
589 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
591 while ( itMeshElems->more() ) {
592 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
593 SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator();
594 while ( itElemNodes->more() ) {
595 const SMDS_MeshNode* aMeshNode = itElemNodes->next();
596 int aNodeID = aMeshNode->GetID();
597 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
598 if ( anIter == nodesMap.end() ) {
599 // filling the nodes coordinates
600 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
601 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
602 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
603 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
606 aNodesConnectivity.push_back(anIter->second);
609 // filling the elements types
610 SMDSAbs_ElementType aType = aMeshElem->GetType();
611 bool isPoly = aMeshElem->IsPoly();
612 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
613 myPreviewData->elementTypes[i].isPoly = isPoly;
614 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
617 myPreviewData->nodesXYZ.length( j );
619 // filling the elements connectivities
620 list<int>::iterator aConnIter = aNodesConnectivity.begin();
621 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
622 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
623 myPreviewData->elementConnectivities[i] = *aConnIter;
625 return myPreviewData._retn();
627 SMESH_CATCH( SMESH::throwCorbaException );
631 //================================================================================
633 * \brief Returns list of it's IDs of created nodes
634 * \retval SMESH::long_array* - list of node ID
636 //================================================================================
638 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
639 throw (SALOME::SALOME_Exception)
642 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
644 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
645 myLastCreatedNodes->length( aSeq.Length() );
646 for (int i = 1; i <= aSeq.Length(); i++)
647 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
649 return myLastCreatedNodes._retn();
650 SMESH_CATCH( SMESH::throwCorbaException );
654 //================================================================================
656 * \brief Returns list of it's IDs of created elements
657 * \retval SMESH::long_array* - list of elements' ID
659 //================================================================================
661 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
662 throw (SALOME::SALOME_Exception)
665 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
667 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
668 myLastCreatedElems->length( aSeq.Length() );
669 for ( int i = 1; i <= aSeq.Length(); i++ )
670 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
672 return myLastCreatedElems._retn();
673 SMESH_CATCH( SMESH::throwCorbaException );
677 //=======================================================================
678 //function : ClearLastCreated
679 //purpose : Clears sequences of last created elements and nodes
680 //=======================================================================
682 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
685 getEditor().CrearLastCreated();
686 SMESH_CATCH( SMESH::throwCorbaException );
689 //=======================================================================
691 * Returns description of an error/warning occured during the last operation
692 * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
694 //=======================================================================
696 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
697 throw (SALOME::SALOME_Exception)
700 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
701 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
702 if ( errIn && !errIn->IsOK() )
704 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
705 errOut->comment = errIn->myComment.c_str();
706 errOut->subShapeID = -1;
707 errOut->hasBadMesh = !errIn->myBadElements.empty();
712 errOut->subShapeID = -1;
713 errOut->hasBadMesh = false;
716 return errOut._retn();
717 SMESH_CATCH( SMESH::throwCorbaException );
721 //=======================================================================
722 //function : MakeIDSource
723 //purpose : Wrap a sequence of ids in a SMESH_IDSource.
724 // Call UnRegister() as you fininsh using it!!
725 //=======================================================================
727 struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource,
728 public virtual SALOME::GenericObj_i
730 SMESH::long_array _ids;
731 SMESH::ElementType _type;
732 SMESH::SMESH_Mesh_ptr _mesh;
733 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
734 SMESH::long_array* GetMeshInfo() { return 0; }
735 SMESH::long_array* GetNbElementsByType()
737 SMESH::long_array_var aRes = new SMESH::long_array();
738 aRes->length(SMESH::NB_ELEMENT_TYPES);
739 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
740 aRes[ i ] = ( i == _type ) ? _ids.length() : 0;
743 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
744 bool IsMeshInfoCorrect() { return true; }
745 SMESH::array_of_ElementType* GetTypes()
747 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
748 if ( _ids.length() > 0 ) {
752 return types._retn();
756 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
757 SMESH::ElementType type)
759 // if ( myAuxIDSources.size() > 10 ) {
760 // delete myAuxIDSources.front();
761 // myAuxIDSources.pop_front();
764 _IDSource* idSrc = new _IDSource;
765 idSrc->_mesh = myMesh_i->_this();
768 //myAuxIDSources.push_back( idSrc );
770 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
772 return anIDSourceVar._retn();
775 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
777 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
780 CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource,
783 if ( _IDSource* tmpIdSource = SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource ))
785 nbIds = (int) tmpIdSource->_ids.length();
786 return & tmpIdSource->_ids[0];
792 // void SMESH_MeshEditor_i::deleteAuxIDSources()
794 // std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
795 // for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
797 // myAuxIDSources.clear();
800 //=============================================================================
804 //=============================================================================
807 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
808 throw (SALOME::SALOME_Exception)
815 for (int i = 0; i < IDsOfElements.length(); i++)
816 IdList.push_back( IDsOfElements[i] );
818 // Update Python script
819 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
822 bool ret = getEditor().Remove( IdList, false );
824 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
827 SMESH_CATCH( SMESH::throwCorbaException );
831 //=============================================================================
835 //=============================================================================
837 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
838 throw (SALOME::SALOME_Exception)
844 for (int i = 0; i < IDsOfNodes.length(); i++)
845 IdList.push_back( IDsOfNodes[i] );
847 // Update Python script
848 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
850 bool ret = getEditor().Remove( IdList, true );
852 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
855 SMESH_CATCH( SMESH::throwCorbaException );
859 //=============================================================================
863 //=============================================================================
865 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
866 throw (SALOME::SALOME_Exception)
871 // Update Python script
872 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
874 // Create filter to find all orphan nodes
875 SMESH::Controls::Filter::TIdSequence seq;
876 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
877 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
879 // remove orphan nodes (if there are any)
881 for ( int i = 0; i < seq.size(); i++ )
882 IdList.push_back( seq[i] );
884 int nbNodesBefore = myMesh->NbNodes();
885 getEditor().Remove( IdList, true );
886 int nbNodesAfter = myMesh->NbNodes();
888 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
889 return nbNodesBefore - nbNodesAfter;
891 SMESH_CATCH( SMESH::throwCorbaException );
895 //=============================================================================
899 //=============================================================================
901 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
902 throw (SALOME::SALOME_Exception)
907 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
909 // Update Python script
910 TPythonDump() << "nodeID = " << this << ".AddNode( "
911 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
913 declareMeshModified( /*isReComputeSafe=*/false );
916 SMESH_CATCH( SMESH::throwCorbaException );
920 //=============================================================================
922 * Create 0D element on the given node.
924 //=============================================================================
926 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
927 throw (SALOME::SALOME_Exception)
932 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
933 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
935 // Update Python script
936 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
938 declareMeshModified( /*isReComputeSafe=*/false );
940 return elem ? elem->GetID() : 0;
942 SMESH_CATCH( SMESH::throwCorbaException );
946 //=============================================================================
948 * Create a ball element on the given node.
950 //=============================================================================
952 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
953 throw (SALOME::SALOME_Exception)
958 if ( diameter < std::numeric_limits<double>::min() )
959 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
961 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
962 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
964 // Update Python script
965 TPythonDump() << "ballElem = "
966 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
968 declareMeshModified( /*isReComputeSafe=*/false );
969 return elem ? elem->GetID() : 0;
971 SMESH_CATCH( SMESH::throwCorbaException );
975 //=============================================================================
977 * Create an edge, either linear and quadratic (this is determed
978 * by number of given nodes, two or three)
980 //=============================================================================
982 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
983 throw (SALOME::SALOME_Exception)
988 int NbNodes = IDsOfNodes.length();
989 SMDS_MeshElement* elem = 0;
992 CORBA::Long index1 = IDsOfNodes[0];
993 CORBA::Long index2 = IDsOfNodes[1];
994 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
995 getMeshDS()->FindNode(index2));
997 // Update Python script
998 TPythonDump() << "edge = " << this << ".AddEdge([ "
999 << index1 << ", " << index2 <<" ])";
1002 CORBA::Long n1 = IDsOfNodes[0];
1003 CORBA::Long n2 = IDsOfNodes[1];
1004 CORBA::Long n12 = IDsOfNodes[2];
1005 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
1006 getMeshDS()->FindNode(n2),
1007 getMeshDS()->FindNode(n12));
1008 // Update Python script
1009 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
1010 <<n1<<", "<<n2<<", "<<n12<<" ])";
1013 declareMeshModified( /*isReComputeSafe=*/false );
1014 return elem ? elem->GetID() : 0;
1016 SMESH_CATCH( SMESH::throwCorbaException );
1020 //=============================================================================
1024 //=============================================================================
1026 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1027 throw (SALOME::SALOME_Exception)
1032 int NbNodes = IDsOfNodes.length();
1038 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1039 for (int i = 0; i < NbNodes; i++)
1040 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1042 SMDS_MeshElement* elem = 0;
1044 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1045 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1046 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1047 nodes[4], nodes[5]); break;
1048 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1049 nodes[4], nodes[5], nodes[6]); break;
1050 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1051 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1052 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1053 nodes[4], nodes[5], nodes[6], nodes[7],
1055 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1058 // Update Python script
1059 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1061 declareMeshModified( /*isReComputeSafe=*/false );
1063 return elem ? elem->GetID() : 0;
1065 SMESH_CATCH( SMESH::throwCorbaException );
1069 //=============================================================================
1073 //=============================================================================
1074 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1075 throw (SALOME::SALOME_Exception)
1080 int NbNodes = IDsOfNodes.length();
1081 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1082 for (int i = 0; i < NbNodes; i++)
1083 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1085 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1087 // Update Python script
1088 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1090 declareMeshModified( /*isReComputeSafe=*/false );
1091 return elem ? elem->GetID() : 0;
1093 SMESH_CATCH( SMESH::throwCorbaException );
1097 //=============================================================================
1099 * Create volume, either linear and quadratic (this is determed
1100 * by number of given nodes)
1102 //=============================================================================
1104 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1105 throw (SALOME::SALOME_Exception)
1110 int NbNodes = IDsOfNodes.length();
1111 vector< const SMDS_MeshNode*> n(NbNodes);
1112 for(int i=0;i<NbNodes;i++)
1113 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1115 SMDS_MeshElement* elem = 0;
1118 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1119 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1120 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1121 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1122 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1123 n[6],n[7],n[8],n[9]);
1125 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1126 n[6],n[7],n[8],n[9],n[10],n[11]);
1128 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1129 n[7],n[8],n[9],n[10],n[11],n[12]);
1131 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1132 n[9],n[10],n[11],n[12],n[13],n[14]);
1134 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1135 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1136 n[15],n[16],n[17],n[18],n[19]);
1138 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1139 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1140 n[15],n[16],n[17],n[18],n[19],
1141 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1145 // Update Python script
1146 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1148 declareMeshModified( /*isReComputeSafe=*/false );
1149 return elem ? elem->GetID() : 0;
1151 SMESH_CATCH( SMESH::throwCorbaException );
1155 //=============================================================================
1157 * AddPolyhedralVolume
1159 //=============================================================================
1160 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1161 const SMESH::long_array & Quantities)
1162 throw (SALOME::SALOME_Exception)
1167 int NbNodes = IDsOfNodes.length();
1168 std::vector<const SMDS_MeshNode*> n (NbNodes);
1169 for (int i = 0; i < NbNodes; i++)
1171 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1172 if (!aNode) return 0;
1176 int NbFaces = Quantities.length();
1177 std::vector<int> q (NbFaces);
1178 for (int j = 0; j < NbFaces; j++)
1179 q[j] = Quantities[j];
1181 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1183 // Update Python script
1184 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1185 << IDsOfNodes << ", " << Quantities << " )";
1187 declareMeshModified( /*isReComputeSafe=*/false );
1188 return elem ? elem->GetID() : 0;
1190 SMESH_CATCH( SMESH::throwCorbaException );
1194 //=============================================================================
1196 * AddPolyhedralVolumeByFaces
1198 //=============================================================================
1200 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1201 throw (SALOME::SALOME_Exception)
1206 int NbFaces = IdsOfFaces.length();
1207 std::vector<const SMDS_MeshNode*> poly_nodes;
1208 std::vector<int> quantities (NbFaces);
1210 for (int i = 0; i < NbFaces; i++) {
1211 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1212 quantities[i] = aFace->NbNodes();
1214 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1215 while (It->more()) {
1216 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1220 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1222 // Update Python script
1223 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1224 << IdsOfFaces << " )";
1226 declareMeshModified( /*isReComputeSafe=*/false );
1227 return elem ? elem->GetID() : 0;
1229 SMESH_CATCH( SMESH::throwCorbaException );
1233 //=============================================================================
1235 // \brief Create 0D elements on all nodes of the given object except those
1236 // nodes on which a 0D element already exists.
1237 // \param theObject object on whose nodes 0D elements will be created.
1238 // \param theGroupName optional name of a group to add 0D elements created
1239 // and/or found on nodes of \a theObject.
1240 // \return an object (a new group or a temporary SMESH_IDSource) holding
1241 // ids of new and/or found 0D elements.
1243 //=============================================================================
1245 SMESH::SMESH_IDSource_ptr
1246 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1247 const char* theGroupName)
1248 throw (SALOME::SALOME_Exception)
1253 SMESH::SMESH_IDSource_var result;
1256 TIDSortedElemSet elements, elems0D;
1257 prepareIdSource( theObject );
1258 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1259 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1261 SMESH::long_array_var newElems = new SMESH::long_array;
1262 newElems->length( elems0D.size() );
1263 TIDSortedElemSet::iterator eIt = elems0D.begin();
1264 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1265 newElems[ i ] = (*eIt)->GetID();
1267 SMESH::SMESH_GroupBase_var groupToFill;
1268 if ( theGroupName && strlen( theGroupName ))
1270 // Get existing group named theGroupName
1271 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1272 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1273 SMESH::SMESH_GroupBase_var group = groups[i];
1274 if ( !group->_is_nil() ) {
1275 CORBA::String_var name = group->GetName();
1276 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1277 groupToFill = group;
1282 if ( groupToFill->_is_nil() )
1283 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1284 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1285 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1288 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1290 group_i->Add( newElems );
1291 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1292 pyDump << groupToFill;
1296 result = MakeIDSource( newElems, SMESH::ELEM0D );
1297 pyDump << "elem0DIDs";
1300 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1301 << theObject << ", '" << theGroupName << "' )";
1303 return result._retn();
1305 SMESH_CATCH( SMESH::throwCorbaException );
1309 //=============================================================================
1311 * \brief Bind a node to a vertex
1312 * \param NodeID - node ID
1313 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1314 * \retval boolean - false if NodeID or VertexID is invalid
1316 //=============================================================================
1318 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1319 throw (SALOME::SALOME_Exception)
1323 SMESHDS_Mesh * mesh = getMeshDS();
1324 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1326 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1328 if ( mesh->MaxShapeIndex() < VertexID )
1329 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1331 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1332 if ( shape.ShapeType() != TopAbs_VERTEX )
1333 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1335 mesh->SetNodeOnVertex( node, VertexID );
1337 myMesh->SetIsModified( true );
1339 SMESH_CATCH( SMESH::throwCorbaException );
1342 //=============================================================================
1344 * \brief Store node position on an edge
1345 * \param NodeID - node ID
1346 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1347 * \param paramOnEdge - parameter on edge where the node is located
1348 * \retval boolean - false if any parameter is invalid
1350 //=============================================================================
1352 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1353 CORBA::Double paramOnEdge)
1354 throw (SALOME::SALOME_Exception)
1358 SMESHDS_Mesh * mesh = getMeshDS();
1359 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1361 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1363 if ( mesh->MaxShapeIndex() < EdgeID )
1364 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1366 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1367 if ( shape.ShapeType() != TopAbs_EDGE )
1368 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1371 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1372 if ( paramOnEdge < f || paramOnEdge > l )
1373 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1375 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1377 myMesh->SetIsModified( true );
1379 SMESH_CATCH( SMESH::throwCorbaException );
1382 //=============================================================================
1384 * \brief Store node position on a face
1385 * \param NodeID - node ID
1386 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1387 * \param u - U parameter on face where the node is located
1388 * \param v - V parameter on face where the node is located
1389 * \retval boolean - false if any parameter is invalid
1391 //=============================================================================
1393 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1394 CORBA::Double u, CORBA::Double v)
1395 throw (SALOME::SALOME_Exception)
1398 SMESHDS_Mesh * mesh = getMeshDS();
1399 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1401 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1403 if ( mesh->MaxShapeIndex() < FaceID )
1404 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1406 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1407 if ( shape.ShapeType() != TopAbs_FACE )
1408 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1410 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1411 bool isOut = ( u < surf.FirstUParameter() ||
1412 u > surf.LastUParameter() ||
1413 v < surf.FirstVParameter() ||
1414 v > surf.LastVParameter() );
1418 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1419 << " u( " << surf.FirstUParameter()
1420 << "," << surf.LastUParameter()
1421 << ") v( " << surf.FirstVParameter()
1422 << "," << surf.LastVParameter() << ")" );
1424 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1427 mesh->SetNodeOnFace( node, FaceID, u, v );
1428 myMesh->SetIsModified( true );
1430 SMESH_CATCH( SMESH::throwCorbaException );
1433 //=============================================================================
1435 * \brief Bind a node to a solid
1436 * \param NodeID - node ID
1437 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1438 * \retval boolean - false if NodeID or SolidID is invalid
1440 //=============================================================================
1442 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1443 throw (SALOME::SALOME_Exception)
1446 SMESHDS_Mesh * mesh = getMeshDS();
1447 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1449 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1451 if ( mesh->MaxShapeIndex() < SolidID )
1452 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1454 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1455 if ( shape.ShapeType() != TopAbs_SOLID &&
1456 shape.ShapeType() != TopAbs_SHELL)
1457 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1459 mesh->SetNodeInVolume( node, SolidID );
1461 SMESH_CATCH( SMESH::throwCorbaException );
1464 //=============================================================================
1466 * \brief Bind an element to a shape
1467 * \param ElementID - element ID
1468 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1470 //=============================================================================
1472 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1473 CORBA::Long ShapeID)
1474 throw (SALOME::SALOME_Exception)
1477 SMESHDS_Mesh * mesh = getMeshDS();
1478 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1480 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1482 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1483 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1485 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1486 if ( shape.ShapeType() != TopAbs_EDGE &&
1487 shape.ShapeType() != TopAbs_FACE &&
1488 shape.ShapeType() != TopAbs_SOLID &&
1489 shape.ShapeType() != TopAbs_SHELL )
1490 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1492 mesh->SetMeshElementOnShape( elem, ShapeID );
1494 myMesh->SetIsModified( true );
1496 SMESH_CATCH( SMESH::throwCorbaException );
1499 //=============================================================================
1503 //=============================================================================
1505 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1506 CORBA::Long NodeID2)
1507 throw (SALOME::SALOME_Exception)
1512 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1513 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1517 // Update Python script
1518 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1519 << NodeID1 << ", " << NodeID2 << " )";
1521 int ret = getEditor().InverseDiag ( n1, n2 );
1523 declareMeshModified( /*isReComputeSafe=*/false );
1526 SMESH_CATCH( SMESH::throwCorbaException );
1530 //=============================================================================
1534 //=============================================================================
1536 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1537 CORBA::Long NodeID2)
1538 throw (SALOME::SALOME_Exception)
1543 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1544 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1548 // Update Python script
1549 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1550 << NodeID1 << ", " << NodeID2 << " )";
1553 bool stat = getEditor().DeleteDiag ( n1, n2 );
1555 declareMeshModified( /*isReComputeSafe=*/!stat );
1559 SMESH_CATCH( SMESH::throwCorbaException );
1563 //=============================================================================
1567 //=============================================================================
1569 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1570 throw (SALOME::SALOME_Exception)
1575 for (int i = 0; i < IDsOfElements.length(); i++)
1577 CORBA::Long index = IDsOfElements[i];
1578 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1580 getEditor().Reorient( elem );
1582 // Update Python script
1583 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1585 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1588 SMESH_CATCH( SMESH::throwCorbaException );
1592 //=============================================================================
1596 //=============================================================================
1598 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1599 throw (SALOME::SALOME_Exception)
1604 TPythonDump aTPythonDump; // suppress dump in Reorient()
1606 prepareIdSource( theObject );
1608 SMESH::long_array_var anElementsId = theObject->GetIDs();
1609 CORBA::Boolean isDone = Reorient(anElementsId);
1611 // Update Python script
1612 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1614 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1617 SMESH_CATCH( SMESH::throwCorbaException );
1621 //=======================================================================
1622 //function : Reorient2D
1623 //purpose : Reorient faces contained in \a the2Dgroup.
1624 // the2Dgroup - the mesh or its part to reorient
1625 // theDirection - desired direction of normal of \a theFace
1626 // theFace - ID of face whose orientation is checked.
1627 // It can be < 1 then \a thePoint is used to find a face.
1628 // thePoint - is used to find a face if \a theFace < 1.
1629 // return number of reoriented elements.
1630 //=======================================================================
1632 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1633 const SMESH::DirStruct& theDirection,
1634 CORBA::Long theFace,
1635 const SMESH::PointStruct& thePoint)
1636 throw (SALOME::SALOME_Exception)
1639 initData(/*deleteSearchers=*/false);
1641 TIDSortedElemSet elements;
1642 prepareIdSource( the2Dgroup );
1643 if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
1644 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1647 const SMDS_MeshElement* face = 0;
1650 face = getMeshDS()->FindElement( theFace );
1652 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1653 if ( face->GetType() != SMDSAbs_Face )
1654 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1658 // create theElementSearcher if needed
1659 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1660 if ( !theElementSearcher )
1662 if ( elements.empty() ) // search in the whole mesh
1664 if ( myMesh->NbFaces() == 0 )
1665 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1667 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1671 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1672 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1674 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1678 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1679 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1682 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1683 if ( !elements.empty() && !elements.count( face ))
1684 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1687 const SMESH::PointStruct * P = &theDirection.PS;
1688 gp_Vec dirVec( P->x, P->y, P->z );
1689 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1690 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1692 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1695 declareMeshModified( /*isReComputeSafe=*/false );
1697 TPythonDump() << this << ".Reorient2D( "
1698 << the2Dgroup << ", "
1699 << theDirection << ", "
1701 << thePoint << " )";
1705 SMESH_CATCH( SMESH::throwCorbaException );
1709 //=============================================================================
1711 * \brief Fuse neighbour triangles into quadrangles.
1713 //=============================================================================
1715 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1716 SMESH::NumericalFunctor_ptr Criterion,
1717 CORBA::Double MaxAngle)
1718 throw (SALOME::SALOME_Exception)
1723 SMESHDS_Mesh* aMesh = getMeshDS();
1724 TIDSortedElemSet faces;
1725 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1727 SMESH::NumericalFunctor_i* aNumericalFunctor =
1728 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1729 SMESH::Controls::NumericalFunctorPtr aCrit;
1730 if ( !aNumericalFunctor )
1731 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1733 aCrit = aNumericalFunctor->GetNumericalFunctor();
1735 // Update Python script
1736 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1737 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1740 bool stat = getEditor().TriToQuad( faces, aCrit, MaxAngle );
1742 declareMeshModified( /*isReComputeSafe=*/!stat );
1745 SMESH_CATCH( SMESH::throwCorbaException );
1749 //=============================================================================
1751 * \brief Fuse neighbour triangles into quadrangles.
1753 //=============================================================================
1755 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1756 SMESH::NumericalFunctor_ptr Criterion,
1757 CORBA::Double MaxAngle)
1758 throw (SALOME::SALOME_Exception)
1763 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1765 prepareIdSource( theObject );
1766 SMESH::long_array_var anElementsId = theObject->GetIDs();
1767 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1769 SMESH::NumericalFunctor_i* aNumericalFunctor =
1770 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1772 // Update Python script
1773 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1774 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1778 SMESH_CATCH( SMESH::throwCorbaException );
1782 //=============================================================================
1784 * \brief Split quadrangles into triangles.
1786 //=============================================================================
1788 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1789 SMESH::NumericalFunctor_ptr Criterion)
1790 throw (SALOME::SALOME_Exception)
1795 SMESHDS_Mesh* aMesh = getMeshDS();
1796 TIDSortedElemSet faces;
1797 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1799 SMESH::NumericalFunctor_i* aNumericalFunctor =
1800 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1801 SMESH::Controls::NumericalFunctorPtr aCrit;
1802 if ( !aNumericalFunctor )
1803 aCrit.reset( new SMESH::Controls::AspectRatio() );
1805 aCrit = aNumericalFunctor->GetNumericalFunctor();
1808 // Update Python script
1809 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1811 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1813 declareMeshModified( /*isReComputeSafe=*/false );
1816 SMESH_CATCH( SMESH::throwCorbaException );
1820 //=============================================================================
1822 * \brief Split quadrangles into triangles.
1824 //=============================================================================
1826 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1827 SMESH::NumericalFunctor_ptr Criterion)
1828 throw (SALOME::SALOME_Exception)
1833 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1835 prepareIdSource( theObject );
1836 SMESH::long_array_var anElementsId = theObject->GetIDs();
1837 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1839 SMESH::NumericalFunctor_i* aNumericalFunctor =
1840 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1842 // Update Python script
1843 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1845 declareMeshModified( /*isReComputeSafe=*/false );
1848 SMESH_CATCH( SMESH::throwCorbaException );
1852 //================================================================================
1854 * \brief Split each of quadrangles into 4 triangles.
1855 * \param [in] theObject - theQuads Container of quadrangles to split.
1857 //================================================================================
1859 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1860 throw (SALOME::SALOME_Exception)
1865 TIDSortedElemSet faces;
1866 prepareIdSource( theObject );
1867 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1869 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1871 getEditor().QuadTo4Tri( faces );
1872 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1874 SMESH_CATCH( SMESH::throwCorbaException );
1877 //=============================================================================
1879 * \brief Split quadrangles into triangles.
1881 //=============================================================================
1883 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1884 CORBA::Boolean Diag13)
1885 throw (SALOME::SALOME_Exception)
1890 SMESHDS_Mesh* aMesh = getMeshDS();
1891 TIDSortedElemSet faces;
1892 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1894 // Update Python script
1895 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1896 << IDsOfElements << ", " << Diag13 << " )";
1898 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1900 declareMeshModified( /*isReComputeSafe=*/ !stat );
1903 SMESH_CATCH( SMESH::throwCorbaException );
1907 //=============================================================================
1909 * \brief Split quadrangles into triangles.
1911 //=============================================================================
1913 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1914 CORBA::Boolean Diag13)
1915 throw (SALOME::SALOME_Exception)
1920 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1922 prepareIdSource( theObject );
1923 SMESH::long_array_var anElementsId = theObject->GetIDs();
1924 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1926 // Update Python script
1927 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1928 << theObject << ", " << Diag13 << " )";
1930 declareMeshModified( /*isReComputeSafe=*/!isDone );
1933 SMESH_CATCH( SMESH::throwCorbaException );
1938 //=============================================================================
1940 * Find better splitting of the given quadrangle.
1941 * \param IDOfQuad ID of the quadrangle to be splitted.
1942 * \param Criterion A criterion to choose a diagonal for splitting.
1943 * \return 1 if 1-3 diagonal is better, 2 if 2-4
1944 * diagonal is better, 0 if error occurs.
1946 //=============================================================================
1948 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1949 SMESH::NumericalFunctor_ptr Criterion)
1950 throw (SALOME::SALOME_Exception)
1955 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
1956 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1958 SMESH::NumericalFunctor_i* aNumericalFunctor =
1959 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1960 SMESH::Controls::NumericalFunctorPtr aCrit;
1961 if (aNumericalFunctor)
1962 aCrit = aNumericalFunctor->GetNumericalFunctor();
1964 aCrit.reset(new SMESH::Controls::AspectRatio());
1966 int id = getEditor().BestSplit(quad, aCrit);
1967 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
1970 SMESH_CATCH( SMESH::throwCorbaException );
1974 //================================================================================
1976 * \brief Split volumic elements into tetrahedrons
1978 //================================================================================
1980 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1981 CORBA::Short methodFlags)
1982 throw (SALOME::SALOME_Exception)
1987 prepareIdSource( elems );
1988 SMESH::long_array_var anElementsId = elems->GetIDs();
1989 TIDSortedElemSet elemSet;
1990 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume );
1992 getEditor().SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1993 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
1995 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1996 << elems << ", " << methodFlags << " )";
1998 SMESH_CATCH( SMESH::throwCorbaException );
2001 //=======================================================================
2004 //=======================================================================
2007 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2008 const SMESH::long_array & IDsOfFixedNodes,
2009 CORBA::Long MaxNbOfIterations,
2010 CORBA::Double MaxAspectRatio,
2011 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2012 throw (SALOME::SALOME_Exception)
2014 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2015 MaxAspectRatio, Method, false );
2019 //=======================================================================
2020 //function : SmoothParametric
2022 //=======================================================================
2025 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2026 const SMESH::long_array & IDsOfFixedNodes,
2027 CORBA::Long MaxNbOfIterations,
2028 CORBA::Double MaxAspectRatio,
2029 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2030 throw (SALOME::SALOME_Exception)
2032 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2033 MaxAspectRatio, Method, true );
2037 //=======================================================================
2038 //function : SmoothObject
2040 //=======================================================================
2043 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2044 const SMESH::long_array & IDsOfFixedNodes,
2045 CORBA::Long MaxNbOfIterations,
2046 CORBA::Double MaxAspectRatio,
2047 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2048 throw (SALOME::SALOME_Exception)
2050 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2051 MaxAspectRatio, Method, false);
2055 //=======================================================================
2056 //function : SmoothParametricObject
2058 //=======================================================================
2061 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2062 const SMESH::long_array & IDsOfFixedNodes,
2063 CORBA::Long MaxNbOfIterations,
2064 CORBA::Double MaxAspectRatio,
2065 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2066 throw (SALOME::SALOME_Exception)
2068 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2069 MaxAspectRatio, Method, true);
2073 //=============================================================================
2077 //=============================================================================
2080 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2081 const SMESH::long_array & IDsOfFixedNodes,
2082 CORBA::Long MaxNbOfIterations,
2083 CORBA::Double MaxAspectRatio,
2084 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2086 throw (SALOME::SALOME_Exception)
2091 SMESHDS_Mesh* aMesh = getMeshDS();
2093 TIDSortedElemSet elements;
2094 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2096 set<const SMDS_MeshNode*> fixedNodes;
2097 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
2098 CORBA::Long index = IDsOfFixedNodes[i];
2099 const SMDS_MeshNode * node = aMesh->FindNode(index);
2101 fixedNodes.insert( node );
2103 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2104 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2105 method = ::SMESH_MeshEditor::CENTROIDAL;
2107 getEditor().Smooth(elements, fixedNodes, method,
2108 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2110 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2112 // Update Python script
2113 TPythonDump() << "isDone = " << this << "."
2114 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2115 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2116 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2117 << "SMESH.SMESH_MeshEditor."
2118 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2119 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2123 SMESH_CATCH( SMESH::throwCorbaException );
2127 //=============================================================================
2131 //=============================================================================
2134 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2135 const SMESH::long_array & IDsOfFixedNodes,
2136 CORBA::Long MaxNbOfIterations,
2137 CORBA::Double MaxAspectRatio,
2138 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2140 throw (SALOME::SALOME_Exception)
2145 TPythonDump aTPythonDump; // suppress dump in smooth()
2147 prepareIdSource( theObject );
2148 SMESH::long_array_var anElementsId = theObject->GetIDs();
2149 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2150 MaxAspectRatio, Method, IsParametric);
2152 // Update Python script
2153 aTPythonDump << "isDone = " << this << "."
2154 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2155 << theObject << ", " << IDsOfFixedNodes << ", "
2156 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2157 << "SMESH.SMESH_MeshEditor."
2158 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2159 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2163 SMESH_CATCH( SMESH::throwCorbaException );
2167 //=============================================================================
2171 //=============================================================================
2173 void SMESH_MeshEditor_i::RenumberNodes()
2174 throw (SALOME::SALOME_Exception)
2177 // Update Python script
2178 TPythonDump() << this << ".RenumberNodes()";
2180 getMeshDS()->Renumber( true );
2182 SMESH_CATCH( SMESH::throwCorbaException );
2185 //=============================================================================
2189 //=============================================================================
2191 void SMESH_MeshEditor_i::RenumberElements()
2192 throw (SALOME::SALOME_Exception)
2195 // Update Python script
2196 TPythonDump() << this << ".RenumberElements()";
2198 getMeshDS()->Renumber( false );
2200 SMESH_CATCH( SMESH::throwCorbaException );
2203 //=======================================================================
2205 * \brief Return groups by their IDs
2207 //=======================================================================
2209 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2210 throw (SALOME::SALOME_Exception)
2215 myMesh_i->CreateGroupServants();
2216 return myMesh_i->GetGroups( *groupIDs );
2218 SMESH_CATCH( SMESH::throwCorbaException );
2222 //=======================================================================
2223 //function : rotationSweep
2225 //=======================================================================
2227 SMESH::ListOfGroups*
2228 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2229 const SMESH::AxisStruct & theAxis,
2230 CORBA::Double theAngleInRadians,
2231 CORBA::Long theNbOfSteps,
2232 CORBA::Double theTolerance,
2233 const bool theMakeGroups,
2234 const SMDSAbs_ElementType theElementType)
2235 throw (SALOME::SALOME_Exception)
2240 TIDSortedElemSet inElements, copyElements;
2241 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2243 TIDSortedElemSet* workElements = & inElements;
2244 bool makeWalls=true;
2245 if ( myIsPreviewMode )
2247 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2248 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2249 workElements = & copyElements;
2250 //makeWalls = false;
2253 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2254 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2256 ::SMESH_MeshEditor::PGroupIDs groupIds =
2257 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2258 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2260 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2262 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2264 SMESH_CATCH( SMESH::throwCorbaException );
2268 //=======================================================================
2269 //function : RotationSweep
2271 //=======================================================================
2273 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2274 const SMESH::AxisStruct & theAxis,
2275 CORBA::Double theAngleInRadians,
2276 CORBA::Long theNbOfSteps,
2277 CORBA::Double theTolerance)
2278 throw (SALOME::SALOME_Exception)
2280 if ( !myIsPreviewMode ) {
2281 TPythonDump() << this << ".RotationSweep( "
2282 << theIDsOfElements << ", "
2284 << TVar( theAngleInRadians ) << ", "
2285 << TVar( theNbOfSteps ) << ", "
2286 << TVar( theTolerance ) << " )";
2288 rotationSweep(theIDsOfElements,
2296 //=======================================================================
2297 //function : RotationSweepMakeGroups
2299 //=======================================================================
2301 SMESH::ListOfGroups*
2302 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2303 const SMESH::AxisStruct& theAxis,
2304 CORBA::Double theAngleInRadians,
2305 CORBA::Long theNbOfSteps,
2306 CORBA::Double theTolerance)
2307 throw (SALOME::SALOME_Exception)
2309 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2311 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2317 if (!myIsPreviewMode) {
2318 dumpGroupsList(aPythonDump, aGroups);
2319 aPythonDump << this << ".RotationSweepMakeGroups( "
2320 << theIDsOfElements << ", "
2322 << TVar( theAngleInRadians ) << ", "
2323 << TVar( theNbOfSteps ) << ", "
2324 << TVar( theTolerance ) << " )";
2329 //=======================================================================
2330 //function : RotationSweepObject
2332 //=======================================================================
2334 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2335 const SMESH::AxisStruct & theAxis,
2336 CORBA::Double theAngleInRadians,
2337 CORBA::Long theNbOfSteps,
2338 CORBA::Double theTolerance)
2339 throw (SALOME::SALOME_Exception)
2341 if ( !myIsPreviewMode ) {
2342 TPythonDump() << this << ".RotationSweepObject( "
2343 << theObject << ", "
2345 << theAngleInRadians << ", "
2346 << theNbOfSteps << ", "
2347 << theTolerance << " )";
2349 prepareIdSource( theObject );
2350 SMESH::long_array_var anElementsId = theObject->GetIDs();
2351 rotationSweep(anElementsId,
2359 //=======================================================================
2360 //function : RotationSweepObject1D
2362 //=======================================================================
2364 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2365 const SMESH::AxisStruct & theAxis,
2366 CORBA::Double theAngleInRadians,
2367 CORBA::Long theNbOfSteps,
2368 CORBA::Double theTolerance)
2369 throw (SALOME::SALOME_Exception)
2371 if ( !myIsPreviewMode ) {
2372 TPythonDump() << this << ".RotationSweepObject1D( "
2373 << theObject << ", "
2375 << TVar( theAngleInRadians ) << ", "
2376 << TVar( theNbOfSteps ) << ", "
2377 << TVar( theTolerance ) << " )";
2379 prepareIdSource( theObject );
2380 SMESH::long_array_var anElementsId = theObject->GetIDs();
2381 rotationSweep(anElementsId,
2390 //=======================================================================
2391 //function : RotationSweepObject2D
2393 //=======================================================================
2395 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2396 const SMESH::AxisStruct & theAxis,
2397 CORBA::Double theAngleInRadians,
2398 CORBA::Long theNbOfSteps,
2399 CORBA::Double theTolerance)
2400 throw (SALOME::SALOME_Exception)
2402 if ( !myIsPreviewMode ) {
2403 TPythonDump() << this << ".RotationSweepObject2D( "
2404 << theObject << ", "
2406 << TVar( theAngleInRadians ) << ", "
2407 << TVar( theNbOfSteps ) << ", "
2408 << TVar( theTolerance ) << " )";
2410 prepareIdSource( theObject );
2411 SMESH::long_array_var anElementsId = theObject->GetIDs();
2412 rotationSweep(anElementsId,
2421 //=======================================================================
2422 //function : RotationSweepObjectMakeGroups
2424 //=======================================================================
2426 SMESH::ListOfGroups*
2427 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2428 const SMESH::AxisStruct& theAxis,
2429 CORBA::Double theAngleInRadians,
2430 CORBA::Long theNbOfSteps,
2431 CORBA::Double theTolerance)
2432 throw (SALOME::SALOME_Exception)
2434 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2436 prepareIdSource( theObject );
2437 SMESH::long_array_var anElementsId = theObject->GetIDs();
2438 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2444 if (!myIsPreviewMode) {
2445 dumpGroupsList(aPythonDump, aGroups);
2446 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2447 << theObject << ", "
2449 << theAngleInRadians << ", "
2450 << theNbOfSteps << ", "
2451 << theTolerance << " )";
2456 //=======================================================================
2457 //function : RotationSweepObject1DMakeGroups
2459 //=======================================================================
2461 SMESH::ListOfGroups*
2462 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2463 const SMESH::AxisStruct& theAxis,
2464 CORBA::Double theAngleInRadians,
2465 CORBA::Long theNbOfSteps,
2466 CORBA::Double theTolerance)
2467 throw (SALOME::SALOME_Exception)
2469 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2471 prepareIdSource( theObject );
2472 SMESH::long_array_var anElementsId = theObject->GetIDs();
2473 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2480 if (!myIsPreviewMode) {
2481 dumpGroupsList(aPythonDump, aGroups);
2482 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2483 << theObject << ", "
2485 << TVar( theAngleInRadians ) << ", "
2486 << TVar( theNbOfSteps ) << ", "
2487 << TVar( theTolerance ) << " )";
2492 //=======================================================================
2493 //function : RotationSweepObject2DMakeGroups
2495 //=======================================================================
2497 SMESH::ListOfGroups*
2498 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2499 const SMESH::AxisStruct& theAxis,
2500 CORBA::Double theAngleInRadians,
2501 CORBA::Long theNbOfSteps,
2502 CORBA::Double theTolerance)
2503 throw (SALOME::SALOME_Exception)
2505 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2507 prepareIdSource( theObject );
2508 SMESH::long_array_var anElementsId = theObject->GetIDs();
2509 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2516 if (!myIsPreviewMode) {
2517 dumpGroupsList(aPythonDump, aGroups);
2518 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2519 << theObject << ", "
2521 << TVar( theAngleInRadians ) << ", "
2522 << TVar( theNbOfSteps ) << ", "
2523 << TVar( theTolerance ) << " )";
2529 //=======================================================================
2530 //function : extrusionSweep
2532 //=======================================================================
2534 SMESH::ListOfGroups*
2535 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2536 const SMESH::DirStruct & theStepVector,
2537 CORBA::Long theNbOfSteps,
2539 const SMDSAbs_ElementType theElementType)
2540 throw (SALOME::SALOME_Exception)
2545 TIDSortedElemSet elements, copyElements;
2546 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2548 const SMESH::PointStruct * P = &theStepVector.PS;
2549 gp_Vec stepVec( P->x, P->y, P->z );
2551 TIDSortedElemSet* workElements = & elements;
2553 SMDSAbs_ElementType aType = SMDSAbs_Face;
2554 if (theElementType == SMDSAbs_Node)
2556 aType = SMDSAbs_Edge;
2558 if ( myIsPreviewMode ) {
2559 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2560 getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
2561 workElements = & copyElements;
2562 theMakeGroups = false;
2565 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2566 ::SMESH_MeshEditor::PGroupIDs groupIds =
2567 getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2569 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2571 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2573 SMESH_CATCH( SMESH::throwCorbaException );
2577 //=======================================================================
2578 //function : ExtrusionSweep
2580 //=======================================================================
2582 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2583 const SMESH::DirStruct & theStepVector,
2584 CORBA::Long theNbOfSteps)
2585 throw (SALOME::SALOME_Exception)
2587 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2588 if (!myIsPreviewMode) {
2589 TPythonDump() << this << ".ExtrusionSweep( "
2590 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2594 //=======================================================================
2595 //function : ExtrusionSweep0D
2597 //=======================================================================
2599 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2600 const SMESH::DirStruct & theStepVector,
2601 CORBA::Long theNbOfSteps)
2602 throw (SALOME::SALOME_Exception)
2604 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2605 if (!myIsPreviewMode) {
2606 TPythonDump() << this << ".ExtrusionSweep0D( "
2607 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2611 //=======================================================================
2612 //function : ExtrusionSweepObject
2614 //=======================================================================
2616 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2617 const SMESH::DirStruct & theStepVector,
2618 CORBA::Long theNbOfSteps)
2619 throw (SALOME::SALOME_Exception)
2621 prepareIdSource( theObject );
2622 SMESH::long_array_var anElementsId = theObject->GetIDs();
2623 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2624 if (!myIsPreviewMode) {
2625 TPythonDump() << this << ".ExtrusionSweepObject( "
2626 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2630 //=======================================================================
2631 //function : ExtrusionSweepObject0D
2633 //=======================================================================
2635 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2636 const SMESH::DirStruct & theStepVector,
2637 CORBA::Long theNbOfSteps)
2638 throw (SALOME::SALOME_Exception)
2640 prepareIdSource( theObject );
2641 SMESH::long_array_var anElementsId = theObject->GetIDs();
2642 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2643 if ( !myIsPreviewMode ) {
2644 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2645 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2649 //=======================================================================
2650 //function : ExtrusionSweepObject1D
2652 //=======================================================================
2654 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2655 const SMESH::DirStruct & theStepVector,
2656 CORBA::Long theNbOfSteps)
2657 throw (SALOME::SALOME_Exception)
2659 prepareIdSource( theObject );
2660 SMESH::long_array_var anElementsId = theObject->GetIDs();
2661 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2662 if ( !myIsPreviewMode ) {
2663 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2664 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2668 //=======================================================================
2669 //function : ExtrusionSweepObject2D
2671 //=======================================================================
2673 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2674 const SMESH::DirStruct & theStepVector,
2675 CORBA::Long theNbOfSteps)
2676 throw (SALOME::SALOME_Exception)
2678 prepareIdSource( theObject );
2679 SMESH::long_array_var anElementsId = theObject->GetIDs();
2680 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2681 if ( !myIsPreviewMode ) {
2682 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2683 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2687 //=======================================================================
2688 //function : ExtrusionSweepMakeGroups
2690 //=======================================================================
2692 SMESH::ListOfGroups*
2693 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2694 const SMESH::DirStruct& theStepVector,
2695 CORBA::Long theNbOfSteps)
2696 throw (SALOME::SALOME_Exception)
2698 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2700 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2702 if (!myIsPreviewMode) {
2703 dumpGroupsList(aPythonDump, aGroups);
2704 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2705 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2710 //=======================================================================
2711 //function : ExtrusionSweepMakeGroups0D
2713 //=======================================================================
2715 SMESH::ListOfGroups*
2716 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2717 const SMESH::DirStruct& theStepVector,
2718 CORBA::Long theNbOfSteps)
2719 throw (SALOME::SALOME_Exception)
2721 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2723 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2725 if (!myIsPreviewMode) {
2726 dumpGroupsList(aPythonDump, aGroups);
2727 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2728 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2733 //=======================================================================
2734 //function : ExtrusionSweepObjectMakeGroups
2736 //=======================================================================
2738 SMESH::ListOfGroups*
2739 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2740 const SMESH::DirStruct& theStepVector,
2741 CORBA::Long theNbOfSteps)
2742 throw (SALOME::SALOME_Exception)
2744 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2746 prepareIdSource( theObject );
2747 SMESH::long_array_var anElementsId = theObject->GetIDs();
2748 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2750 if (!myIsPreviewMode) {
2751 dumpGroupsList(aPythonDump, aGroups);
2752 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2753 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2758 //=======================================================================
2759 //function : ExtrusionSweepObject0DMakeGroups
2761 //=======================================================================
2763 SMESH::ListOfGroups*
2764 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2765 const SMESH::DirStruct& theStepVector,
2766 CORBA::Long theNbOfSteps)
2767 throw (SALOME::SALOME_Exception)
2769 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2771 prepareIdSource( theObject );
2772 SMESH::long_array_var anElementsId = theObject->GetIDs();
2773 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2774 theNbOfSteps, true, SMDSAbs_Node);
2775 if (!myIsPreviewMode) {
2776 dumpGroupsList(aPythonDump, aGroups);
2777 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2778 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2783 //=======================================================================
2784 //function : ExtrusionSweepObject1DMakeGroups
2786 //=======================================================================
2788 SMESH::ListOfGroups*
2789 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2790 const SMESH::DirStruct& theStepVector,
2791 CORBA::Long theNbOfSteps)
2792 throw (SALOME::SALOME_Exception)
2794 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2796 prepareIdSource( theObject );
2797 SMESH::long_array_var anElementsId = theObject->GetIDs();
2798 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2799 theNbOfSteps, true, SMDSAbs_Edge);
2800 if (!myIsPreviewMode) {
2801 dumpGroupsList(aPythonDump, aGroups);
2802 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2803 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2808 //=======================================================================
2809 //function : ExtrusionSweepObject2DMakeGroups
2811 //=======================================================================
2813 SMESH::ListOfGroups*
2814 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2815 const SMESH::DirStruct& theStepVector,
2816 CORBA::Long theNbOfSteps)
2817 throw (SALOME::SALOME_Exception)
2819 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2821 prepareIdSource( theObject );
2822 SMESH::long_array_var anElementsId = theObject->GetIDs();
2823 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2824 theNbOfSteps, true, SMDSAbs_Face);
2825 if (!myIsPreviewMode) {
2826 dumpGroupsList(aPythonDump, aGroups);
2827 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2828 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2834 //=======================================================================
2835 //function : advancedExtrusion
2837 //=======================================================================
2839 SMESH::ListOfGroups*
2840 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2841 const SMESH::DirStruct & theStepVector,
2842 CORBA::Long theNbOfSteps,
2843 CORBA::Long theExtrFlags,
2844 CORBA::Double theSewTolerance,
2845 const bool theMakeGroups)
2846 throw (SALOME::SALOME_Exception)
2851 TIDSortedElemSet elements;
2852 arrayToSet(theIDsOfElements, getMeshDS(), elements);
2854 const SMESH::PointStruct * P = &theStepVector.PS;
2855 gp_Vec stepVec( P->x, P->y, P->z );
2857 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2858 ::SMESH_MeshEditor::PGroupIDs groupIds =
2859 getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2860 theMakeGroups, theExtrFlags, theSewTolerance);
2862 declareMeshModified( /*isReComputeSafe=*/true );
2864 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2866 SMESH_CATCH( SMESH::throwCorbaException );
2870 //=======================================================================
2871 //function : AdvancedExtrusion
2873 //=======================================================================
2875 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2876 const SMESH::DirStruct & theStepVector,
2877 CORBA::Long theNbOfSteps,
2878 CORBA::Long theExtrFlags,
2879 CORBA::Double theSewTolerance)
2880 throw (SALOME::SALOME_Exception)
2882 if ( !myIsPreviewMode ) {
2883 TPythonDump() << "stepVector = " << theStepVector;
2884 TPythonDump() << this << ".AdvancedExtrusion("
2887 << theNbOfSteps << ","
2888 << theExtrFlags << ", "
2889 << theSewTolerance << " )";
2891 advancedExtrusion( theIDsOfElements,
2899 //=======================================================================
2900 //function : AdvancedExtrusionMakeGroups
2902 //=======================================================================
2903 SMESH::ListOfGroups*
2904 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2905 const SMESH::DirStruct& theStepVector,
2906 CORBA::Long theNbOfSteps,
2907 CORBA::Long theExtrFlags,
2908 CORBA::Double theSewTolerance)
2909 throw (SALOME::SALOME_Exception)
2911 if (!myIsPreviewMode) {
2912 TPythonDump() << "stepVector = " << theStepVector;
2914 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2916 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2923 if (!myIsPreviewMode) {
2924 dumpGroupsList(aPythonDump, aGroups);
2925 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2928 << theNbOfSteps << ","
2929 << theExtrFlags << ", "
2930 << theSewTolerance << " )";
2936 //================================================================================
2938 * \brief Convert extrusion error to IDL enum
2940 //================================================================================
2942 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2944 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2948 RETCASE( EXTR_NO_ELEMENTS );
2949 RETCASE( EXTR_PATH_NOT_EDGE );
2950 RETCASE( EXTR_BAD_PATH_SHAPE );
2951 RETCASE( EXTR_BAD_STARTING_NODE );
2952 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2953 RETCASE( EXTR_CANT_GET_TANGENT );
2955 return SMESH::SMESH_MeshEditor::EXTR_OK;
2959 //=======================================================================
2960 //function : extrusionAlongPath
2962 //=======================================================================
2963 SMESH::ListOfGroups*
2964 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2965 SMESH::SMESH_Mesh_ptr thePathMesh,
2966 GEOM::GEOM_Object_ptr thePathShape,
2967 CORBA::Long theNodeStart,
2968 CORBA::Boolean theHasAngles,
2969 const SMESH::double_array & theAngles,
2970 CORBA::Boolean theHasRefPoint,
2971 const SMESH::PointStruct & theRefPoint,
2972 const bool theMakeGroups,
2973 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2974 const SMDSAbs_ElementType theElementType)
2975 throw (SALOME::SALOME_Exception)
2978 MESSAGE("extrusionAlongPath");
2981 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2982 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2985 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2987 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2988 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2990 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2991 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2995 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2997 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3001 TIDSortedElemSet elements;
3002 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
3004 list<double> angles;
3005 for (int i = 0; i < theAngles.length(); i++) {
3006 angles.push_back( theAngles[i] );
3009 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
3011 int nbOldGroups = myMesh->NbGroup();
3013 ::SMESH_MeshEditor::Extrusion_Error error =
3014 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
3015 theHasAngles, angles, false,
3016 theHasRefPoint, refPnt, theMakeGroups );
3018 declareMeshModified( /*isReComputeSafe=*/true );
3019 theError = convExtrError( error );
3021 if ( theMakeGroups ) {
3022 list<int> groupIDs = myMesh->GetGroupIds();
3023 list<int>::iterator newBegin = groupIDs.begin();
3024 std::advance( newBegin, nbOldGroups ); // skip old groups
3025 groupIDs.erase( groupIDs.begin(), newBegin );
3026 return getGroups( & groupIDs );
3030 SMESH_CATCH( SMESH::throwCorbaException );
3034 //=======================================================================
3035 //function : extrusionAlongPathX
3037 //=======================================================================
3039 SMESH::ListOfGroups*
3040 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
3041 SMESH::SMESH_IDSource_ptr Path,
3042 CORBA::Long NodeStart,
3043 CORBA::Boolean HasAngles,
3044 const SMESH::double_array& Angles,
3045 CORBA::Boolean LinearVariation,
3046 CORBA::Boolean HasRefPoint,
3047 const SMESH::PointStruct& RefPoint,
3049 const SMDSAbs_ElementType ElementType,
3050 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
3051 throw (SALOME::SALOME_Exception)
3054 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
3058 list<double> angles;
3059 for (int i = 0; i < Angles.length(); i++) {
3060 angles.push_back( Angles[i] );
3062 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
3063 int nbOldGroups = myMesh->NbGroup();
3065 if ( Path->_is_nil() ) {
3066 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3070 TIDSortedElemSet elements, copyElements;
3071 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
3073 TIDSortedElemSet* workElements = &elements;
3075 if ( myIsPreviewMode )
3077 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
3078 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
3079 workElements = & copyElements;
3083 ::SMESH_MeshEditor::Extrusion_Error error;
3085 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
3088 SMDS_MeshNode* aNodeStart =
3089 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3090 if ( !aNodeStart ) {
3091 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3094 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
3095 HasAngles, angles, LinearVariation,
3096 HasRefPoint, refPnt, MakeGroups );
3097 declareMeshModified( /*isReComputeSafe=*/true );
3099 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
3102 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
3103 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
3104 SMDS_MeshNode* aNodeStart =
3105 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3106 if ( !aNodeStart ) {
3107 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3110 SMESH_subMesh* aSubMesh =
3111 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
3112 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
3113 HasAngles, angles, LinearVariation,
3114 HasRefPoint, refPnt, MakeGroups );
3115 declareMeshModified( /*isReComputeSafe=*/true );
3117 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
3119 // path as group of 1D elements
3125 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3129 Error = convExtrError( error );
3132 list<int> groupIDs = myMesh->GetGroupIds();
3133 list<int>::iterator newBegin = groupIDs.begin();
3134 std::advance( newBegin, nbOldGroups ); // skip old groups
3135 groupIDs.erase( groupIDs.begin(), newBegin );
3136 return getGroups( & groupIDs );
3140 SMESH_CATCH( SMESH::throwCorbaException );
3144 //=======================================================================
3145 //function : ExtrusionAlongPath
3147 //=======================================================================
3149 SMESH::SMESH_MeshEditor::Extrusion_Error
3150 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3151 SMESH::SMESH_Mesh_ptr thePathMesh,
3152 GEOM::GEOM_Object_ptr thePathShape,
3153 CORBA::Long theNodeStart,
3154 CORBA::Boolean theHasAngles,
3155 const SMESH::double_array & theAngles,
3156 CORBA::Boolean theHasRefPoint,
3157 const SMESH::PointStruct & theRefPoint)
3158 throw (SALOME::SALOME_Exception)
3160 MESSAGE("ExtrusionAlongPath");
3161 if ( !myIsPreviewMode ) {
3162 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
3163 << theIDsOfElements << ", "
3164 << thePathMesh << ", "
3165 << thePathShape << ", "
3166 << theNodeStart << ", "
3167 << theHasAngles << ", "
3168 << theAngles << ", "
3169 << theHasRefPoint << ", "
3170 << "SMESH.PointStruct( "
3171 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3172 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3173 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3175 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3176 extrusionAlongPath( theIDsOfElements,
3189 //=======================================================================
3190 //function : ExtrusionAlongPathObject
3192 //=======================================================================
3194 SMESH::SMESH_MeshEditor::Extrusion_Error
3195 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
3196 SMESH::SMESH_Mesh_ptr thePathMesh,
3197 GEOM::GEOM_Object_ptr thePathShape,
3198 CORBA::Long theNodeStart,
3199 CORBA::Boolean theHasAngles,
3200 const SMESH::double_array & theAngles,
3201 CORBA::Boolean theHasRefPoint,
3202 const SMESH::PointStruct & theRefPoint)
3203 throw (SALOME::SALOME_Exception)
3205 if ( !myIsPreviewMode ) {
3206 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
3207 << theObject << ", "
3208 << thePathMesh << ", "
3209 << thePathShape << ", "
3210 << theNodeStart << ", "
3211 << theHasAngles << ", "
3212 << theAngles << ", "
3213 << theHasRefPoint << ", "
3214 << "SMESH.PointStruct( "
3215 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3216 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3217 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3219 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3220 prepareIdSource( theObject );
3221 SMESH::long_array_var anElementsId = theObject->GetIDs();
3222 extrusionAlongPath( anElementsId,
3235 //=======================================================================
3236 //function : ExtrusionAlongPathObject1D
3238 //=======================================================================
3240 SMESH::SMESH_MeshEditor::Extrusion_Error
3241 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
3242 SMESH::SMESH_Mesh_ptr thePathMesh,
3243 GEOM::GEOM_Object_ptr thePathShape,
3244 CORBA::Long theNodeStart,
3245 CORBA::Boolean theHasAngles,
3246 const SMESH::double_array & theAngles,
3247 CORBA::Boolean theHasRefPoint,
3248 const SMESH::PointStruct & theRefPoint)
3249 throw (SALOME::SALOME_Exception)
3251 if ( !myIsPreviewMode ) {
3252 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
3253 << theObject << ", "
3254 << thePathMesh << ", "
3255 << thePathShape << ", "
3256 << theNodeStart << ", "
3257 << theHasAngles << ", "
3258 << theAngles << ", "
3259 << theHasRefPoint << ", "
3260 << "SMESH.PointStruct( "
3261 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3262 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3263 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3265 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3266 prepareIdSource( theObject );
3267 SMESH::long_array_var anElementsId = theObject->GetIDs();
3268 extrusionAlongPath( anElementsId,
3282 //=======================================================================
3283 //function : ExtrusionAlongPathObject2D
3285 //=======================================================================
3287 SMESH::SMESH_MeshEditor::Extrusion_Error
3288 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3289 SMESH::SMESH_Mesh_ptr thePathMesh,
3290 GEOM::GEOM_Object_ptr thePathShape,
3291 CORBA::Long theNodeStart,
3292 CORBA::Boolean theHasAngles,
3293 const SMESH::double_array & theAngles,
3294 CORBA::Boolean theHasRefPoint,
3295 const SMESH::PointStruct & theRefPoint)
3296 throw (SALOME::SALOME_Exception)
3298 if ( !myIsPreviewMode ) {
3299 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3300 << theObject << ", "
3301 << thePathMesh << ", "
3302 << thePathShape << ", "
3303 << theNodeStart << ", "
3304 << theHasAngles << ", "
3305 << theAngles << ", "
3306 << theHasRefPoint << ", "
3307 << "SMESH.PointStruct( "
3308 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3309 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3310 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3312 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3313 prepareIdSource( theObject );
3314 SMESH::long_array_var anElementsId = theObject->GetIDs();
3315 extrusionAlongPath( anElementsId,
3330 //=======================================================================
3331 //function : ExtrusionAlongPathMakeGroups
3333 //=======================================================================
3335 SMESH::ListOfGroups*
3336 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3337 SMESH::SMESH_Mesh_ptr thePathMesh,
3338 GEOM::GEOM_Object_ptr thePathShape,
3339 CORBA::Long theNodeStart,
3340 CORBA::Boolean theHasAngles,
3341 const SMESH::double_array& theAngles,
3342 CORBA::Boolean theHasRefPoint,
3343 const SMESH::PointStruct& theRefPoint,
3344 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3345 throw (SALOME::SALOME_Exception)
3347 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3349 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3359 if (!myIsPreviewMode) {
3360 bool isDumpGroups = aGroups && aGroups->length() > 0;
3362 aPythonDump << "(" << aGroups << ", error)";
3364 aPythonDump <<"error";
3366 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3367 << theIDsOfElements << ", "
3368 << thePathMesh << ", "
3369 << thePathShape << ", "
3370 << theNodeStart << ", "
3371 << theHasAngles << ", "
3372 << theAngles << ", "
3373 << theHasRefPoint << ", "
3374 << "SMESH.PointStruct( "
3375 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3376 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3377 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3382 //=======================================================================
3383 //function : ExtrusionAlongPathObjectMakeGroups
3385 //=======================================================================
3387 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3388 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3389 SMESH::SMESH_Mesh_ptr thePathMesh,
3390 GEOM::GEOM_Object_ptr thePathShape,
3391 CORBA::Long theNodeStart,
3392 CORBA::Boolean theHasAngles,
3393 const SMESH::double_array& theAngles,
3394 CORBA::Boolean theHasRefPoint,
3395 const SMESH::PointStruct& theRefPoint,
3396 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3397 throw (SALOME::SALOME_Exception)
3399 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3401 prepareIdSource( theObject );
3402 SMESH::long_array_var anElementsId = theObject->GetIDs();
3403 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3414 if (!myIsPreviewMode) {
3415 bool isDumpGroups = aGroups && aGroups->length() > 0;
3417 aPythonDump << "(" << aGroups << ", error)";
3419 aPythonDump <<"error";
3421 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3422 << theObject << ", "
3423 << thePathMesh << ", "
3424 << thePathShape << ", "
3425 << theNodeStart << ", "
3426 << theHasAngles << ", "
3427 << theAngles << ", "
3428 << theHasRefPoint << ", "
3429 << "SMESH.PointStruct( "
3430 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3431 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3432 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3437 //=======================================================================
3438 //function : ExtrusionAlongPathObject1DMakeGroups
3440 //=======================================================================
3442 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3443 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3444 SMESH::SMESH_Mesh_ptr thePathMesh,
3445 GEOM::GEOM_Object_ptr thePathShape,
3446 CORBA::Long theNodeStart,
3447 CORBA::Boolean theHasAngles,
3448 const SMESH::double_array& theAngles,
3449 CORBA::Boolean theHasRefPoint,
3450 const SMESH::PointStruct& theRefPoint,
3451 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3452 throw (SALOME::SALOME_Exception)
3454 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3456 prepareIdSource( theObject );
3457 SMESH::long_array_var anElementsId = theObject->GetIDs();
3458 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3470 if (!myIsPreviewMode) {
3471 bool isDumpGroups = aGroups && aGroups->length() > 0;
3473 aPythonDump << "(" << aGroups << ", error)";
3475 aPythonDump << "error";
3477 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3478 << theObject << ", "
3479 << thePathMesh << ", "
3480 << thePathShape << ", "
3481 << theNodeStart << ", "
3482 << theHasAngles << ", "
3483 << theAngles << ", "
3484 << theHasRefPoint << ", "
3485 << "SMESH.PointStruct( "
3486 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3487 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3488 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3493 //=======================================================================
3494 //function : ExtrusionAlongPathObject2DMakeGroups
3496 //=======================================================================
3498 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3499 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3500 SMESH::SMESH_Mesh_ptr thePathMesh,
3501 GEOM::GEOM_Object_ptr thePathShape,
3502 CORBA::Long theNodeStart,
3503 CORBA::Boolean theHasAngles,
3504 const SMESH::double_array& theAngles,
3505 CORBA::Boolean theHasRefPoint,
3506 const SMESH::PointStruct& theRefPoint,
3507 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3508 throw (SALOME::SALOME_Exception)
3510 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3512 prepareIdSource( theObject );
3513 SMESH::long_array_var anElementsId = theObject->GetIDs();
3514 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3526 if (!myIsPreviewMode) {
3527 bool isDumpGroups = aGroups && aGroups->length() > 0;
3529 aPythonDump << "(" << aGroups << ", error)";
3531 aPythonDump << "error";
3533 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3534 << theObject << ", "
3535 << thePathMesh << ", "
3536 << thePathShape << ", "
3537 << theNodeStart << ", "
3538 << theHasAngles << ", "
3539 << theAngles << ", "
3540 << theHasRefPoint << ", "
3541 << "SMESH.PointStruct( "
3542 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3543 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3544 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3549 //=======================================================================
3550 //function : ExtrusionAlongPathObjX
3552 //=======================================================================
3554 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3555 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3556 SMESH::SMESH_IDSource_ptr Path,
3557 CORBA::Long NodeStart,
3558 CORBA::Boolean HasAngles,
3559 const SMESH::double_array& Angles,
3560 CORBA::Boolean LinearVariation,
3561 CORBA::Boolean HasRefPoint,
3562 const SMESH::PointStruct& RefPoint,
3563 CORBA::Boolean MakeGroups,
3564 SMESH::ElementType ElemType,
3565 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3566 throw (SALOME::SALOME_Exception)
3568 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3570 prepareIdSource( Object );
3571 SMESH::long_array_var anElementsId = Object->GetIDs();
3572 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3581 (SMDSAbs_ElementType)ElemType,
3584 if (!myIsPreviewMode) {
3585 bool isDumpGroups = aGroups && aGroups->length() > 0;
3587 aPythonDump << "(" << *aGroups << ", error)";
3589 aPythonDump << "error";
3591 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3594 << NodeStart << ", "
3595 << HasAngles << ", "
3596 << TVar( Angles ) << ", "
3597 << LinearVariation << ", "
3598 << HasRefPoint << ", "
3599 << "SMESH.PointStruct( "
3600 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3601 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3602 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3603 << MakeGroups << ", "
3604 << ElemType << " )";
3609 //=======================================================================
3610 //function : ExtrusionAlongPathX
3612 //=======================================================================
3614 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3615 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3616 SMESH::SMESH_IDSource_ptr Path,
3617 CORBA::Long NodeStart,
3618 CORBA::Boolean HasAngles,
3619 const SMESH::double_array& Angles,
3620 CORBA::Boolean LinearVariation,
3621 CORBA::Boolean HasRefPoint,
3622 const SMESH::PointStruct& RefPoint,
3623 CORBA::Boolean MakeGroups,
3624 SMESH::ElementType ElemType,
3625 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3626 throw (SALOME::SALOME_Exception)
3628 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3630 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3639 (SMDSAbs_ElementType)ElemType,
3642 if (!myIsPreviewMode) {
3643 bool isDumpGroups = aGroups && aGroups->length() > 0;
3645 aPythonDump << "(" << *aGroups << ", error)";
3647 aPythonDump <<"error";
3649 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3650 << IDsOfElements << ", "
3652 << NodeStart << ", "
3653 << HasAngles << ", "
3654 << TVar( Angles ) << ", "
3655 << LinearVariation << ", "
3656 << HasRefPoint << ", "
3657 << "SMESH.PointStruct( "
3658 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3659 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3660 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3661 << MakeGroups << ", "
3662 << ElemType << " )";
3667 //================================================================================
3669 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3670 * of given angles along path steps
3671 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3672 * which proceeds the extrusion
3673 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3674 * is used to define the sub-mesh for the path
3676 //================================================================================
3678 SMESH::double_array*
3679 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3680 GEOM::GEOM_Object_ptr thePathShape,
3681 const SMESH::double_array & theAngles)
3683 SMESH::double_array_var aResult = new SMESH::double_array();
3684 int nbAngles = theAngles.length();
3685 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3687 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3688 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3689 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3690 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3691 return aResult._retn();
3692 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3693 if ( nbSteps == nbAngles )
3695 aResult.inout() = theAngles;
3699 aResult->length( nbSteps );
3700 double rAn2St = double( nbAngles ) / double( nbSteps );
3701 double angPrev = 0, angle;
3702 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3704 double angCur = rAn2St * ( iSt+1 );
3705 double angCurFloor = floor( angCur );
3706 double angPrevFloor = floor( angPrev );
3707 if ( angPrevFloor == angCurFloor )
3708 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3711 int iP = int( angPrevFloor );
3712 double angPrevCeil = ceil(angPrev);
3713 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3715 int iC = int( angCurFloor );
3716 if ( iC < nbAngles )
3717 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3719 iP = int( angPrevCeil );
3721 angle += theAngles[ iC ];
3723 aResult[ iSt ] = angle;
3728 // Update Python script
3729 TPythonDump() << "rotAngles = " << theAngles;
3730 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3731 << thePathMesh << ", "
3732 << thePathShape << ", "
3735 return aResult._retn();
3738 //=======================================================================
3741 //=======================================================================
3743 SMESH::ListOfGroups*
3744 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3745 const SMESH::AxisStruct & theAxis,
3746 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3747 CORBA::Boolean theCopy,
3749 ::SMESH_Mesh* theTargetMesh)
3750 throw (SALOME::SALOME_Exception)
3755 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3756 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3758 if ( theTargetMesh )
3762 switch ( theMirrorType ) {
3763 case SMESH::SMESH_MeshEditor::POINT:
3764 aTrsf.SetMirror( P );
3766 case SMESH::SMESH_MeshEditor::AXIS:
3767 aTrsf.SetMirror( gp_Ax1( P, V ));
3770 aTrsf.SetMirror( gp_Ax2( P, V ));
3773 TIDSortedElemSet copyElements;
3774 TIDSortedElemSet* workElements = & theElements;
3776 if ( myIsPreviewMode )
3778 TPreviewMesh * tmpMesh = getPreviewMesh();
3779 tmpMesh->Copy( theElements, copyElements);
3780 if ( !theCopy && !theTargetMesh )
3782 TIDSortedElemSet elemsAround, elemsAroundCopy;
3783 getElementsAround( theElements, getMeshDS(), elemsAround );
3784 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3786 workElements = & copyElements;
3787 theMakeGroups = false;
3790 ::SMESH_MeshEditor::PGroupIDs groupIds =
3791 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3793 if ( theCopy && !myIsPreviewMode)
3795 if ( theTargetMesh )
3797 theTargetMesh->GetMeshDS()->Modified();
3801 declareMeshModified( /*isReComputeSafe=*/false );
3804 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3806 SMESH_CATCH( SMESH::throwCorbaException );
3810 //=======================================================================
3813 //=======================================================================
3815 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3816 const SMESH::AxisStruct & theAxis,
3817 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3818 CORBA::Boolean theCopy)
3819 throw (SALOME::SALOME_Exception)
3821 if ( !myIsPreviewMode ) {
3822 TPythonDump() << this << ".Mirror( "
3823 << theIDsOfElements << ", "
3825 << mirrorTypeName(theMirrorType) << ", "
3828 if ( theIDsOfElements.length() > 0 )
3830 TIDSortedElemSet elements;
3831 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3832 mirror(elements, theAxis, theMirrorType, theCopy, false);
3837 //=======================================================================
3838 //function : MirrorObject
3840 //=======================================================================
3842 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3843 const SMESH::AxisStruct & theAxis,
3844 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3845 CORBA::Boolean theCopy)
3846 throw (SALOME::SALOME_Exception)
3848 if ( !myIsPreviewMode ) {
3849 TPythonDump() << this << ".MirrorObject( "
3850 << theObject << ", "
3852 << mirrorTypeName(theMirrorType) << ", "
3855 TIDSortedElemSet elements;
3857 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3859 prepareIdSource( theObject );
3860 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3861 mirror(elements, theAxis, theMirrorType, theCopy, false);
3864 //=======================================================================
3865 //function : MirrorMakeGroups
3867 //=======================================================================
3869 SMESH::ListOfGroups*
3870 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3871 const SMESH::AxisStruct& theMirror,
3872 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3873 throw (SALOME::SALOME_Exception)
3875 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3877 SMESH::ListOfGroups * aGroups = 0;
3878 if ( theIDsOfElements.length() > 0 )
3880 TIDSortedElemSet elements;
3881 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3882 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3884 if (!myIsPreviewMode) {
3885 dumpGroupsList(aPythonDump, aGroups);
3886 aPythonDump << this << ".MirrorMakeGroups( "
3887 << theIDsOfElements << ", "
3888 << theMirror << ", "
3889 << mirrorTypeName(theMirrorType) << " )";
3894 //=======================================================================
3895 //function : MirrorObjectMakeGroups
3897 //=======================================================================
3899 SMESH::ListOfGroups*
3900 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3901 const SMESH::AxisStruct& theMirror,
3902 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3903 throw (SALOME::SALOME_Exception)
3905 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3907 SMESH::ListOfGroups * aGroups = 0;
3908 TIDSortedElemSet elements;
3909 prepareIdSource( theObject );
3910 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3911 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3913 if (!myIsPreviewMode)
3915 dumpGroupsList(aPythonDump,aGroups);
3916 aPythonDump << this << ".MirrorObjectMakeGroups( "
3917 << theObject << ", "
3918 << theMirror << ", "
3919 << mirrorTypeName(theMirrorType) << " )";
3924 //=======================================================================
3925 //function : MirrorMakeMesh
3927 //=======================================================================
3929 SMESH::SMESH_Mesh_ptr
3930 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3931 const SMESH::AxisStruct& theMirror,
3932 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3933 CORBA::Boolean theCopyGroups,
3934 const char* theMeshName)
3935 throw (SALOME::SALOME_Exception)
3937 SMESH_Mesh_i* mesh_i;
3938 SMESH::SMESH_Mesh_var mesh;
3939 { // open new scope to dump "MakeMesh" command
3940 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3942 TPythonDump pydump; // to prevent dump at mesh creation
3944 mesh = makeMesh( theMeshName );
3945 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3946 if (mesh_i && theIDsOfElements.length() > 0 )
3948 TIDSortedElemSet elements;
3949 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3950 mirror(elements, theMirror, theMirrorType,
3951 false, theCopyGroups, & mesh_i->GetImpl());
3952 mesh_i->CreateGroupServants();
3955 if (!myIsPreviewMode) {
3956 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3957 << theIDsOfElements << ", "
3958 << theMirror << ", "
3959 << mirrorTypeName(theMirrorType) << ", "
3960 << theCopyGroups << ", '"
3961 << theMeshName << "' )";
3966 if (!myIsPreviewMode && mesh_i)
3967 mesh_i->GetGroups();
3969 return mesh._retn();
3972 //=======================================================================
3973 //function : MirrorObjectMakeMesh
3975 //=======================================================================
3977 SMESH::SMESH_Mesh_ptr
3978 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3979 const SMESH::AxisStruct& theMirror,
3980 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3981 CORBA::Boolean theCopyGroups,
3982 const char* theMeshName)
3983 throw (SALOME::SALOME_Exception)
3985 SMESH_Mesh_i* mesh_i;
3986 SMESH::SMESH_Mesh_var mesh;
3987 { // open new scope to dump "MakeMesh" command
3988 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3990 TPythonDump pydump; // to prevent dump at mesh creation
3992 mesh = makeMesh( theMeshName );
3993 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3994 TIDSortedElemSet elements;
3995 prepareIdSource( theObject );
3997 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3999 mirror(elements, theMirror, theMirrorType,
4000 false, theCopyGroups, & mesh_i->GetImpl());
4001 mesh_i->CreateGroupServants();
4003 if (!myIsPreviewMode) {
4004 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
4005 << theObject << ", "
4006 << theMirror << ", "
4007 << mirrorTypeName(theMirrorType) << ", "
4008 << theCopyGroups << ", '"
4009 << theMeshName << "' )";
4014 if (!myIsPreviewMode && mesh_i)
4015 mesh_i->GetGroups();
4017 return mesh._retn();
4020 //=======================================================================
4021 //function : translate
4023 //=======================================================================
4025 SMESH::ListOfGroups*
4026 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
4027 const SMESH::DirStruct & theVector,
4028 CORBA::Boolean theCopy,
4030 ::SMESH_Mesh* theTargetMesh)
4031 throw (SALOME::SALOME_Exception)
4036 if ( theTargetMesh )
4040 const SMESH::PointStruct * P = &theVector.PS;
4041 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
4043 TIDSortedElemSet copyElements;
4044 TIDSortedElemSet* workElements = &theElements;
4046 if ( myIsPreviewMode )
4048 TPreviewMesh * tmpMesh = getPreviewMesh();
4049 tmpMesh->Copy( theElements, copyElements);
4050 if ( !theCopy && !theTargetMesh )
4052 TIDSortedElemSet elemsAround, elemsAroundCopy;
4053 getElementsAround( theElements, getMeshDS(), elemsAround );
4054 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4056 workElements = & copyElements;
4057 theMakeGroups = false;
4060 ::SMESH_MeshEditor::PGroupIDs groupIds =
4061 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4063 if ( theCopy && !myIsPreviewMode )
4065 if ( theTargetMesh )
4067 theTargetMesh->GetMeshDS()->Modified();
4071 declareMeshModified( /*isReComputeSafe=*/false );
4075 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4077 SMESH_CATCH( SMESH::throwCorbaException );
4081 //=======================================================================
4082 //function : Translate
4084 //=======================================================================
4086 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
4087 const SMESH::DirStruct & theVector,
4088 CORBA::Boolean theCopy)
4089 throw (SALOME::SALOME_Exception)
4091 if (!myIsPreviewMode) {
4092 TPythonDump() << this << ".Translate( "
4093 << theIDsOfElements << ", "
4094 << theVector << ", "
4097 if (theIDsOfElements.length()) {
4098 TIDSortedElemSet elements;
4099 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4100 translate(elements, theVector, theCopy, false);
4104 //=======================================================================
4105 //function : TranslateObject
4107 //=======================================================================
4109 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
4110 const SMESH::DirStruct & theVector,
4111 CORBA::Boolean theCopy)
4112 throw (SALOME::SALOME_Exception)
4114 if (!myIsPreviewMode) {
4115 TPythonDump() << this << ".TranslateObject( "
4116 << theObject << ", "
4117 << theVector << ", "
4120 TIDSortedElemSet elements;
4122 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4124 prepareIdSource( theObject );
4125 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4126 translate(elements, theVector, theCopy, false);
4129 //=======================================================================
4130 //function : TranslateMakeGroups
4132 //=======================================================================
4134 SMESH::ListOfGroups*
4135 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
4136 const SMESH::DirStruct& theVector)
4137 throw (SALOME::SALOME_Exception)
4139 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4141 SMESH::ListOfGroups * aGroups = 0;
4142 if (theIDsOfElements.length()) {
4143 TIDSortedElemSet elements;
4144 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4145 aGroups = translate(elements,theVector,true,true);
4147 if (!myIsPreviewMode) {
4148 dumpGroupsList(aPythonDump, aGroups);
4149 aPythonDump << this << ".TranslateMakeGroups( "
4150 << theIDsOfElements << ", "
4151 << theVector << " )";
4156 //=======================================================================
4157 //function : TranslateObjectMakeGroups
4159 //=======================================================================
4161 SMESH::ListOfGroups*
4162 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4163 const SMESH::DirStruct& theVector)
4164 throw (SALOME::SALOME_Exception)
4166 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4168 SMESH::ListOfGroups * aGroups = 0;
4169 TIDSortedElemSet elements;
4170 prepareIdSource( theObject );
4171 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4172 aGroups = translate(elements, theVector, true, true);
4174 if (!myIsPreviewMode) {
4175 dumpGroupsList(aPythonDump, aGroups);
4176 aPythonDump << this << ".TranslateObjectMakeGroups( "
4177 << theObject << ", "
4178 << theVector << " )";
4183 //=======================================================================
4184 //function : TranslateMakeMesh
4186 //=======================================================================
4188 SMESH::SMESH_Mesh_ptr
4189 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
4190 const SMESH::DirStruct& theVector,
4191 CORBA::Boolean theCopyGroups,
4192 const char* theMeshName)
4193 throw (SALOME::SALOME_Exception)
4195 SMESH_Mesh_i* mesh_i;
4196 SMESH::SMESH_Mesh_var mesh;
4198 { // open new scope to dump "MakeMesh" command
4199 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4201 TPythonDump pydump; // to prevent dump at mesh creation
4203 mesh = makeMesh( theMeshName );
4204 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4206 if ( mesh_i && theIDsOfElements.length() )
4208 TIDSortedElemSet elements;
4209 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4210 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
4211 mesh_i->CreateGroupServants();
4214 if ( !myIsPreviewMode ) {
4215 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
4216 << theIDsOfElements << ", "
4217 << theVector << ", "
4218 << theCopyGroups << ", '"
4219 << theMeshName << "' )";
4224 if (!myIsPreviewMode && mesh_i)
4225 mesh_i->GetGroups();
4227 return mesh._retn();
4230 //=======================================================================
4231 //function : TranslateObjectMakeMesh
4233 //=======================================================================
4235 SMESH::SMESH_Mesh_ptr
4236 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4237 const SMESH::DirStruct& theVector,
4238 CORBA::Boolean theCopyGroups,
4239 const char* theMeshName)
4240 throw (SALOME::SALOME_Exception)
4243 SMESH_Mesh_i* mesh_i;
4244 SMESH::SMESH_Mesh_var mesh;
4245 { // open new scope to dump "MakeMesh" command
4246 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4248 TPythonDump pydump; // to prevent dump at mesh creation
4249 mesh = makeMesh( theMeshName );
4250 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4252 TIDSortedElemSet elements;
4253 prepareIdSource( theObject );
4255 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4257 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
4258 mesh_i->CreateGroupServants();
4260 if ( !myIsPreviewMode ) {
4261 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
4262 << theObject << ", "
4263 << theVector << ", "
4264 << theCopyGroups << ", '"
4265 << theMeshName << "' )";
4270 if (!myIsPreviewMode && mesh_i)
4271 mesh_i->GetGroups();
4273 return mesh._retn();
4275 SMESH_CATCH( SMESH::throwCorbaException );
4279 //=======================================================================
4282 //=======================================================================
4284 SMESH::ListOfGroups*
4285 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
4286 const SMESH::AxisStruct & theAxis,
4287 CORBA::Double theAngle,
4288 CORBA::Boolean theCopy,
4290 ::SMESH_Mesh* theTargetMesh)
4291 throw (SALOME::SALOME_Exception)
4296 if ( theTargetMesh )
4299 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
4300 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
4303 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
4305 TIDSortedElemSet copyElements;
4306 TIDSortedElemSet* workElements = &theElements;
4307 if ( myIsPreviewMode ) {
4308 TPreviewMesh * tmpMesh = getPreviewMesh();
4309 tmpMesh->Copy( theElements, copyElements );
4310 if ( !theCopy && !theTargetMesh )
4312 TIDSortedElemSet elemsAround, elemsAroundCopy;
4313 getElementsAround( theElements, getMeshDS(), elemsAround );
4314 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4316 workElements = ©Elements;
4317 theMakeGroups = false;
4320 ::SMESH_MeshEditor::PGroupIDs groupIds =
4321 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4323 if ( theCopy && !myIsPreviewMode)
4325 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4326 else declareMeshModified( /*isReComputeSafe=*/false );
4329 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4331 SMESH_CATCH( SMESH::throwCorbaException );
4335 //=======================================================================
4338 //=======================================================================
4340 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4341 const SMESH::AxisStruct & theAxis,
4342 CORBA::Double theAngle,
4343 CORBA::Boolean theCopy)
4344 throw (SALOME::SALOME_Exception)
4346 if (!myIsPreviewMode) {
4347 TPythonDump() << this << ".Rotate( "
4348 << theIDsOfElements << ", "
4350 << TVar( theAngle ) << ", "
4353 if (theIDsOfElements.length() > 0)
4355 TIDSortedElemSet elements;
4356 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4357 rotate(elements,theAxis,theAngle,theCopy,false);
4361 //=======================================================================
4362 //function : RotateObject
4364 //=======================================================================
4366 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4367 const SMESH::AxisStruct & theAxis,
4368 CORBA::Double theAngle,
4369 CORBA::Boolean theCopy)
4370 throw (SALOME::SALOME_Exception)
4372 if ( !myIsPreviewMode ) {
4373 TPythonDump() << this << ".RotateObject( "
4374 << theObject << ", "
4376 << TVar( theAngle ) << ", "
4379 TIDSortedElemSet elements;
4380 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4381 prepareIdSource( theObject );
4382 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4383 rotate(elements,theAxis,theAngle,theCopy,false);
4386 //=======================================================================
4387 //function : RotateMakeGroups
4389 //=======================================================================
4391 SMESH::ListOfGroups*
4392 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4393 const SMESH::AxisStruct& theAxis,
4394 CORBA::Double theAngle)
4395 throw (SALOME::SALOME_Exception)
4397 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4399 SMESH::ListOfGroups * aGroups = 0;
4400 if (theIDsOfElements.length() > 0)
4402 TIDSortedElemSet elements;
4403 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4404 aGroups = rotate(elements,theAxis,theAngle,true,true);
4406 if (!myIsPreviewMode) {
4407 dumpGroupsList(aPythonDump, aGroups);
4408 aPythonDump << this << ".RotateMakeGroups( "
4409 << theIDsOfElements << ", "
4411 << TVar( theAngle ) << " )";
4416 //=======================================================================
4417 //function : RotateObjectMakeGroups
4419 //=======================================================================
4421 SMESH::ListOfGroups*
4422 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4423 const SMESH::AxisStruct& theAxis,
4424 CORBA::Double theAngle)
4425 throw (SALOME::SALOME_Exception)
4427 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4429 SMESH::ListOfGroups * aGroups = 0;
4430 TIDSortedElemSet elements;
4431 prepareIdSource( theObject );
4432 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4433 aGroups = rotate(elements, theAxis, theAngle, true, true);
4435 if (!myIsPreviewMode) {
4436 dumpGroupsList(aPythonDump, aGroups);
4437 aPythonDump << this << ".RotateObjectMakeGroups( "
4438 << theObject << ", "
4440 << TVar( theAngle ) << " )";
4445 //=======================================================================
4446 //function : RotateMakeMesh
4448 //=======================================================================
4450 SMESH::SMESH_Mesh_ptr
4451 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4452 const SMESH::AxisStruct& theAxis,
4453 CORBA::Double theAngleInRadians,
4454 CORBA::Boolean theCopyGroups,
4455 const char* theMeshName)
4456 throw (SALOME::SALOME_Exception)
4459 SMESH::SMESH_Mesh_var mesh;
4460 SMESH_Mesh_i* mesh_i;
4462 { // open new scope to dump "MakeMesh" command
4463 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4465 TPythonDump pydump; // to prevent dump at mesh creation
4467 mesh = makeMesh( theMeshName );
4468 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4470 if ( mesh_i && theIDsOfElements.length() > 0 )
4472 TIDSortedElemSet elements;
4473 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4474 rotate(elements, theAxis, theAngleInRadians,
4475 false, theCopyGroups, & mesh_i->GetImpl());
4476 mesh_i->CreateGroupServants();
4478 if ( !myIsPreviewMode ) {
4479 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4480 << theIDsOfElements << ", "
4482 << TVar( theAngleInRadians ) << ", "
4483 << theCopyGroups << ", '"
4484 << theMeshName << "' )";
4489 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4490 mesh_i->GetGroups();
4492 return mesh._retn();
4494 SMESH_CATCH( SMESH::throwCorbaException );
4498 //=======================================================================
4499 //function : RotateObjectMakeMesh
4501 //=======================================================================
4503 SMESH::SMESH_Mesh_ptr
4504 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4505 const SMESH::AxisStruct& theAxis,
4506 CORBA::Double theAngleInRadians,
4507 CORBA::Boolean theCopyGroups,
4508 const char* theMeshName)
4509 throw (SALOME::SALOME_Exception)
4512 SMESH::SMESH_Mesh_var mesh;
4513 SMESH_Mesh_i* mesh_i;
4515 {// open new scope to dump "MakeMesh" command
4516 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4518 TPythonDump pydump; // to prevent dump at mesh creation
4519 mesh = makeMesh( theMeshName );
4520 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4522 TIDSortedElemSet elements;
4523 prepareIdSource( theObject );
4525 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4527 rotate(elements, theAxis, theAngleInRadians,
4528 false, theCopyGroups, & mesh_i->GetImpl());
4529 mesh_i->CreateGroupServants();
4531 if ( !myIsPreviewMode ) {
4532 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4533 << theObject << ", "
4535 << TVar( theAngleInRadians ) << ", "
4536 << theCopyGroups << ", '"
4537 << theMeshName << "' )";
4542 if (!myIsPreviewMode && mesh_i)
4543 mesh_i->GetGroups();
4545 return mesh._retn();
4547 SMESH_CATCH( SMESH::throwCorbaException );
4551 //=======================================================================
4554 //=======================================================================
4556 SMESH::ListOfGroups*
4557 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4558 const SMESH::PointStruct& thePoint,
4559 const SMESH::double_array& theScaleFact,
4560 CORBA::Boolean theCopy,
4562 ::SMESH_Mesh* theTargetMesh)
4563 throw (SALOME::SALOME_Exception)
4567 if ( theScaleFact.length() < 1 )
4568 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4569 if ( theScaleFact.length() == 2 )
4570 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4572 if ( theTargetMesh )
4575 TIDSortedElemSet elements;
4576 prepareIdSource( theObject );
4577 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4578 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4583 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4584 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4586 double tol = std::numeric_limits<double>::max();
4588 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4589 0, S[1], 0, thePoint.y * (1-S[1]),
4590 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4592 TIDSortedElemSet copyElements;
4593 TIDSortedElemSet* workElements = &elements;
4594 if ( myIsPreviewMode )
4596 TPreviewMesh * tmpMesh = getPreviewMesh();
4597 tmpMesh->Copy( elements, copyElements);
4598 if ( !theCopy && !theTargetMesh )
4600 TIDSortedElemSet elemsAround, elemsAroundCopy;
4601 getElementsAround( elements, getMeshDS(), elemsAround );
4602 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4604 workElements = & copyElements;
4605 theMakeGroups = false;
4608 ::SMESH_MeshEditor::PGroupIDs groupIds =
4609 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4611 if ( theCopy && !myIsPreviewMode )
4613 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4614 else declareMeshModified( /*isReComputeSafe=*/false );
4616 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4618 SMESH_CATCH( SMESH::throwCorbaException );
4622 //=======================================================================
4625 //=======================================================================
4627 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4628 const SMESH::PointStruct& thePoint,
4629 const SMESH::double_array& theScaleFact,
4630 CORBA::Boolean theCopy)
4631 throw (SALOME::SALOME_Exception)
4633 if ( !myIsPreviewMode ) {
4634 TPythonDump() << this << ".Scale( "
4635 << theObject << ", "
4637 << TVar( theScaleFact ) << ", "
4640 scale(theObject, thePoint, theScaleFact, theCopy, false);
4644 //=======================================================================
4645 //function : ScaleMakeGroups
4647 //=======================================================================
4649 SMESH::ListOfGroups*
4650 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4651 const SMESH::PointStruct& thePoint,
4652 const SMESH::double_array& theScaleFact)
4653 throw (SALOME::SALOME_Exception)
4655 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4657 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4658 if (!myIsPreviewMode) {
4659 dumpGroupsList(aPythonDump, aGroups);
4660 aPythonDump << this << ".Scale("
4663 << TVar( theScaleFact ) << ",True,True)";
4669 //=======================================================================
4670 //function : ScaleMakeMesh
4672 //=======================================================================
4674 SMESH::SMESH_Mesh_ptr
4675 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4676 const SMESH::PointStruct& thePoint,
4677 const SMESH::double_array& theScaleFact,
4678 CORBA::Boolean theCopyGroups,
4679 const char* theMeshName)
4680 throw (SALOME::SALOME_Exception)
4682 SMESH_Mesh_i* mesh_i;
4683 SMESH::SMESH_Mesh_var mesh;
4684 { // open new scope to dump "MakeMesh" command
4685 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4687 TPythonDump pydump; // to prevent dump at mesh creation
4688 mesh = makeMesh( theMeshName );
4689 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4693 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4694 mesh_i->CreateGroupServants();
4696 if ( !myIsPreviewMode )
4697 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4698 << theObject << ", "
4700 << TVar( theScaleFact ) << ", "
4701 << theCopyGroups << ", '"
4702 << theMeshName << "' )";
4706 if (!myIsPreviewMode && mesh_i)
4707 mesh_i->GetGroups();
4709 return mesh._retn();
4713 //=======================================================================
4714 //function : FindCoincidentNodes
4716 //=======================================================================
4718 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4719 SMESH::array_of_long_array_out GroupsOfNodes)
4720 throw (SALOME::SALOME_Exception)
4725 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4726 TIDSortedNodeSet nodes; // no input nodes
4727 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4729 GroupsOfNodes = new SMESH::array_of_long_array;
4730 GroupsOfNodes->length( aListOfListOfNodes.size() );
4731 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4732 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4733 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4734 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4735 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4736 aGroup.length( aListOfNodes.size() );
4737 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4738 aGroup[ j ] = (*lIt)->GetID();
4740 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4741 << Tolerance << " )";
4743 SMESH_CATCH( SMESH::throwCorbaException );
4746 //=======================================================================
4747 //function : FindCoincidentNodesOnPart
4749 //=======================================================================
4751 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4752 CORBA::Double Tolerance,
4753 SMESH::array_of_long_array_out GroupsOfNodes)
4754 throw (SALOME::SALOME_Exception)
4759 TIDSortedNodeSet nodes;
4760 prepareIdSource( theObject );
4761 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4763 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4765 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4767 GroupsOfNodes = new SMESH::array_of_long_array;
4768 GroupsOfNodes->length( aListOfListOfNodes.size() );
4769 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4770 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4772 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4773 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4774 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4775 aGroup.length( aListOfNodes.size() );
4776 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4777 aGroup[ j ] = (*lIt)->GetID();
4779 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4781 << Tolerance << " )";
4783 SMESH_CATCH( SMESH::throwCorbaException );
4786 //================================================================================
4788 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4789 * ExceptSubMeshOrGroups
4791 //================================================================================
4793 void SMESH_MeshEditor_i::
4794 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4795 CORBA::Double theTolerance,
4796 SMESH::array_of_long_array_out theGroupsOfNodes,
4797 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4798 throw (SALOME::SALOME_Exception)
4803 TIDSortedNodeSet nodes;
4804 prepareIdSource( theObject );
4805 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4807 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4809 TIDSortedNodeSet exceptNodes;
4810 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
4811 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4812 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4813 nodes.erase( *avoidNode );
4815 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4817 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4819 theGroupsOfNodes = new SMESH::array_of_long_array;
4820 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4821 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4822 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4824 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4825 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4826 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4827 aGroup.length( aListOfNodes.size() );
4828 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4829 aGroup[ j ] = (*lIt)->GetID();
4831 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4833 << theTolerance << ", "
4834 << theExceptSubMeshOrGroups << " )";
4836 SMESH_CATCH( SMESH::throwCorbaException );
4839 //=======================================================================
4840 //function : MergeNodes
4842 //=======================================================================
4844 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4845 throw (SALOME::SALOME_Exception)
4850 SMESHDS_Mesh* aMesh = getMeshDS();
4852 TPythonDump aTPythonDump;
4853 aTPythonDump << this << ".MergeNodes([";
4854 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4855 for (int i = 0; i < GroupsOfNodes.length(); i++)
4857 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4858 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4859 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4860 for ( int j = 0; j < aNodeGroup.length(); j++ )
4862 CORBA::Long index = aNodeGroup[ j ];
4863 const SMDS_MeshNode * node = aMesh->FindNode(index);
4865 aListOfNodes.push_back( node );
4867 if ( aListOfNodes.size() < 2 )
4868 aListOfListOfNodes.pop_back();
4870 if ( i > 0 ) aTPythonDump << ", ";
4871 aTPythonDump << aNodeGroup;
4873 getEditor().MergeNodes( aListOfListOfNodes );
4875 aTPythonDump << "])";
4877 declareMeshModified( /*isReComputeSafe=*/false );
4879 SMESH_CATCH( SMESH::throwCorbaException );
4882 //=======================================================================
4883 //function : FindEqualElements
4885 //=======================================================================
4887 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4888 SMESH::array_of_long_array_out GroupsOfElementsID)
4889 throw (SALOME::SALOME_Exception)
4894 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4895 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4897 TIDSortedElemSet elems;
4898 prepareIdSource( theObject );
4899 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4901 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4902 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
4904 GroupsOfElementsID = new SMESH::array_of_long_array;
4905 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4907 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4908 aListOfListOfElementsID.begin();
4909 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4911 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4912 list<int>& listOfIDs = *arraysIt;
4913 aGroup.length( listOfIDs.size() );
4914 list<int>::iterator idIt = listOfIDs.begin();
4915 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4916 aGroup[ k ] = *idIt;
4919 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4923 SMESH_CATCH( SMESH::throwCorbaException );
4926 //=======================================================================
4927 //function : MergeElements
4929 //=======================================================================
4931 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4932 throw (SALOME::SALOME_Exception)
4937 TPythonDump aTPythonDump;
4938 aTPythonDump << this << ".MergeElements( [";
4940 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4942 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4943 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4944 aListOfListOfElementsID.push_back( list< int >() );
4945 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4946 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4947 CORBA::Long id = anElemsIDGroup[ j ];
4948 aListOfElemsID.push_back( id );
4950 if ( aListOfElemsID.size() < 2 )
4951 aListOfListOfElementsID.pop_back();
4952 if ( i > 0 ) aTPythonDump << ", ";
4953 aTPythonDump << anElemsIDGroup;
4956 getEditor().MergeElements(aListOfListOfElementsID);
4958 declareMeshModified( /*isReComputeSafe=*/true );
4960 aTPythonDump << "] )";
4962 SMESH_CATCH( SMESH::throwCorbaException );
4965 //=======================================================================
4966 //function : MergeEqualElements
4968 //=======================================================================
4970 void SMESH_MeshEditor_i::MergeEqualElements()
4971 throw (SALOME::SALOME_Exception)
4976 getEditor().MergeEqualElements();
4978 declareMeshModified( /*isReComputeSafe=*/true );
4980 TPythonDump() << this << ".MergeEqualElements()";
4982 SMESH_CATCH( SMESH::throwCorbaException );
4985 //=============================================================================
4987 * Move the node to a given point
4989 //=============================================================================
4991 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4995 throw (SALOME::SALOME_Exception)
4998 initData(/*deleteSearchers=*/false);
5000 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
5004 if ( theNodeSearcher )
5005 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5007 if ( myIsPreviewMode ) // make preview data
5009 // in a preview mesh, make edges linked to a node
5010 TPreviewMesh& tmpMesh = *getPreviewMesh();
5011 TIDSortedElemSet linkedNodes;
5012 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5013 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5014 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
5015 for ( ; nIt != linkedNodes.end(); ++nIt )
5017 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
5018 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
5022 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
5023 // fill preview data
5025 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5026 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5028 getMeshDS()->MoveNode(node, x, y, z);
5030 if ( !myIsPreviewMode )
5032 // Update Python script
5033 TPythonDump() << "isDone = " << this << ".MoveNode( "
5034 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
5035 declareMeshModified( /*isReComputeSafe=*/false );
5038 SMESH_CATCH( SMESH::throwCorbaException );
5043 //================================================================================
5045 * \brief Return ID of node closest to a given point
5047 //================================================================================
5049 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
5052 throw (SALOME::SALOME_Exception)
5055 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5057 if ( !theNodeSearcher ) {
5058 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5061 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
5062 return node->GetID();
5064 SMESH_CATCH( SMESH::throwCorbaException );
5068 //================================================================================
5070 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
5071 * move the node closest to the point to point's location and return ID of the node
5073 //================================================================================
5075 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
5078 CORBA::Long theNodeID)
5079 throw (SALOME::SALOME_Exception)
5082 // We keep theNodeSearcher until any mesh modification:
5083 // 1) initData() deletes theNodeSearcher at any edition,
5084 // 2) TSearchersDeleter - at any mesh compute event and mesh change
5086 initData(/*deleteSearchers=*/false);
5088 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5090 int nodeID = theNodeID;
5091 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
5092 if ( !node ) // preview moving node
5094 if ( !theNodeSearcher ) {
5095 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5098 node = theNodeSearcher->FindClosestTo( p );
5101 nodeID = node->GetID();
5102 if ( myIsPreviewMode ) // make preview data
5104 // in a preview mesh, make edges linked to a node
5105 TPreviewMesh tmpMesh = *getPreviewMesh();
5106 TIDSortedElemSet linkedNodes;
5107 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5108 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5109 for ( ; nIt != linkedNodes.end(); ++nIt )
5111 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
5112 tmpMesh.Copy( &edge );
5115 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
5117 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
5118 // fill preview data
5120 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5122 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5126 getMeshDS()->MoveNode(node, x, y, z);
5130 if ( !myIsPreviewMode )
5132 TPythonDump() << "nodeID = " << this
5133 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
5134 << ", " << nodeID << " )";
5136 declareMeshModified( /*isReComputeSafe=*/false );
5141 SMESH_CATCH( SMESH::throwCorbaException );
5145 //=======================================================================
5147 * Return elements of given type where the given point is IN or ON.
5149 * 'ALL' type means elements of any type excluding nodes
5151 //=======================================================================
5153 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
5156 SMESH::ElementType type)
5157 throw (SALOME::SALOME_Exception)
5160 SMESH::long_array_var res = new SMESH::long_array;
5161 vector< const SMDS_MeshElement* > foundElems;
5163 theSearchersDeleter.Set( myMesh );
5164 if ( !theElementSearcher ) {
5165 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5167 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5168 SMDSAbs_ElementType( type ),
5170 res->length( foundElems.size() );
5171 for ( int i = 0; i < foundElems.size(); ++i )
5172 res[i] = foundElems[i]->GetID();
5174 if ( !myIsPreviewMode ) // call from tui
5175 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
5183 SMESH_CATCH( SMESH::throwCorbaException );
5187 //=======================================================================
5188 //function : FindAmongElementsByPoint
5189 //purpose : Searching among the given elements, return elements of given type
5190 // where the given point is IN or ON.
5191 // 'ALL' type means elements of any type excluding nodes
5192 //=======================================================================
5195 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
5199 SMESH::ElementType type)
5200 throw (SALOME::SALOME_Exception)
5203 SMESH::long_array_var res = new SMESH::long_array;
5205 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
5206 if ( types->length() == 1 && // a part contains only nodes or 0D elements
5207 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
5208 type != types[0] ) // but search of elements of dim > 0
5211 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
5212 return FindElementsByPoint( x,y,z, type );
5214 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
5216 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
5217 if ( !theElementSearcher )
5219 // create a searcher from elementIDs
5220 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
5221 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
5223 if ( !idSourceToSet( elementIDs, meshDS, elements,
5224 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
5227 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5228 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
5230 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
5233 vector< const SMDS_MeshElement* > foundElems;
5235 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5236 SMDSAbs_ElementType( type ),
5238 res->length( foundElems.size() );
5239 for ( int i = 0; i < foundElems.size(); ++i )
5240 res[i] = foundElems[i]->GetID();
5242 if ( !myIsPreviewMode ) // call from tui
5243 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
5244 << elementIDs << ", "
5252 SMESH_CATCH( SMESH::throwCorbaException );
5256 //=======================================================================
5257 //function : GetPointState
5258 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
5259 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
5260 //=======================================================================
5262 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
5265 throw (SALOME::SALOME_Exception)
5268 theSearchersDeleter.Set( myMesh );
5269 if ( !theElementSearcher ) {
5270 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5272 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
5274 SMESH_CATCH( SMESH::throwCorbaException );
5278 //=======================================================================
5279 //function : convError
5281 //=======================================================================
5283 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
5285 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
5289 RETCASE( SEW_BORDER1_NOT_FOUND );
5290 RETCASE( SEW_BORDER2_NOT_FOUND );
5291 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
5292 RETCASE( SEW_BAD_SIDE_NODES );
5293 RETCASE( SEW_VOLUMES_TO_SPLIT );
5294 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
5295 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
5296 RETCASE( SEW_BAD_SIDE1_NODES );
5297 RETCASE( SEW_BAD_SIDE2_NODES );
5299 return SMESH::SMESH_MeshEditor::SEW_OK;
5302 //=======================================================================
5303 //function : SewFreeBorders
5305 //=======================================================================
5307 SMESH::SMESH_MeshEditor::Sew_Error
5308 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
5309 CORBA::Long SecondNodeID1,
5310 CORBA::Long LastNodeID1,
5311 CORBA::Long FirstNodeID2,
5312 CORBA::Long SecondNodeID2,
5313 CORBA::Long LastNodeID2,
5314 CORBA::Boolean CreatePolygons,
5315 CORBA::Boolean CreatePolyedrs)
5316 throw (SALOME::SALOME_Exception)
5321 SMESHDS_Mesh* aMesh = getMeshDS();
5323 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5324 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5325 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5326 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5327 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5328 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
5330 if (!aBorderFirstNode ||
5331 !aBorderSecondNode||
5333 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5334 if (!aSide2FirstNode ||
5335 !aSide2SecondNode ||
5337 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5339 TPythonDump() << "error = " << this << ".SewFreeBorders( "
5340 << FirstNodeID1 << ", "
5341 << SecondNodeID1 << ", "
5342 << LastNodeID1 << ", "
5343 << FirstNodeID2 << ", "
5344 << SecondNodeID2 << ", "
5345 << LastNodeID2 << ", "
5346 << CreatePolygons<< ", "
5347 << CreatePolyedrs<< " )";
5349 SMESH::SMESH_MeshEditor::Sew_Error error =
5350 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5361 declareMeshModified( /*isReComputeSafe=*/false );
5364 SMESH_CATCH( SMESH::throwCorbaException );
5365 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5369 //=======================================================================
5370 //function : SewConformFreeBorders
5372 //=======================================================================
5374 SMESH::SMESH_MeshEditor::Sew_Error
5375 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
5376 CORBA::Long SecondNodeID1,
5377 CORBA::Long LastNodeID1,
5378 CORBA::Long FirstNodeID2,
5379 CORBA::Long SecondNodeID2)
5380 throw (SALOME::SALOME_Exception)
5385 SMESHDS_Mesh* aMesh = getMeshDS();
5387 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5388 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5389 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5390 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5391 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5392 const SMDS_MeshNode* aSide2ThirdNode = 0;
5394 if (!aBorderFirstNode ||
5395 !aBorderSecondNode||
5397 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5398 if (!aSide2FirstNode ||
5400 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5402 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
5403 << FirstNodeID1 << ", "
5404 << SecondNodeID1 << ", "
5405 << LastNodeID1 << ", "
5406 << FirstNodeID2 << ", "
5407 << SecondNodeID2 << " )";
5409 SMESH::SMESH_MeshEditor::Sew_Error error =
5410 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5419 declareMeshModified( /*isReComputeSafe=*/false );
5422 SMESH_CATCH( SMESH::throwCorbaException );
5423 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5427 //=======================================================================
5428 //function : SewBorderToSide
5430 //=======================================================================
5432 SMESH::SMESH_MeshEditor::Sew_Error
5433 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5434 CORBA::Long SecondNodeIDOnFreeBorder,
5435 CORBA::Long LastNodeIDOnFreeBorder,
5436 CORBA::Long FirstNodeIDOnSide,
5437 CORBA::Long LastNodeIDOnSide,
5438 CORBA::Boolean CreatePolygons,
5439 CORBA::Boolean CreatePolyedrs)
5440 throw (SALOME::SALOME_Exception)
5445 SMESHDS_Mesh* aMesh = getMeshDS();
5447 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5448 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5449 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5450 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5451 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5452 const SMDS_MeshNode* aSide2ThirdNode = 0;
5454 if (!aBorderFirstNode ||
5455 !aBorderSecondNode||
5457 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5458 if (!aSide2FirstNode ||
5460 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5462 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5463 << FirstNodeIDOnFreeBorder << ", "
5464 << SecondNodeIDOnFreeBorder << ", "
5465 << LastNodeIDOnFreeBorder << ", "
5466 << FirstNodeIDOnSide << ", "
5467 << LastNodeIDOnSide << ", "
5468 << CreatePolygons << ", "
5469 << CreatePolyedrs << ") ";
5471 SMESH::SMESH_MeshEditor::Sew_Error error =
5472 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5482 declareMeshModified( /*isReComputeSafe=*/false );
5485 SMESH_CATCH( SMESH::throwCorbaException );
5486 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5490 //=======================================================================
5491 //function : SewSideElements
5493 //=======================================================================
5495 SMESH::SMESH_MeshEditor::Sew_Error
5496 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5497 const SMESH::long_array& IDsOfSide2Elements,
5498 CORBA::Long NodeID1OfSide1ToMerge,
5499 CORBA::Long NodeID1OfSide2ToMerge,
5500 CORBA::Long NodeID2OfSide1ToMerge,
5501 CORBA::Long NodeID2OfSide2ToMerge)
5502 throw (SALOME::SALOME_Exception)
5507 SMESHDS_Mesh* aMesh = getMeshDS();
5509 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5510 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5511 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5512 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5514 if (!aFirstNode1ToMerge ||
5515 !aFirstNode2ToMerge )
5516 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5517 if (!aSecondNode1ToMerge||
5518 !aSecondNode2ToMerge)
5519 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5521 TIDSortedElemSet aSide1Elems, aSide2Elems;
5522 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5523 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5525 TPythonDump() << "error = " << this << ".SewSideElements( "
5526 << IDsOfSide1Elements << ", "
5527 << IDsOfSide2Elements << ", "
5528 << NodeID1OfSide1ToMerge << ", "
5529 << NodeID1OfSide2ToMerge << ", "
5530 << NodeID2OfSide1ToMerge << ", "
5531 << NodeID2OfSide2ToMerge << ")";
5533 SMESH::SMESH_MeshEditor::Sew_Error error =
5534 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5537 aSecondNode1ToMerge,
5538 aSecondNode2ToMerge));
5540 declareMeshModified( /*isReComputeSafe=*/false );
5543 SMESH_CATCH( SMESH::throwCorbaException );
5544 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5547 //================================================================================
5549 * \brief Set new nodes for given element
5550 * \param ide - element id
5551 * \param newIDs - new node ids
5552 * \retval CORBA::Boolean - true if result is OK
5554 //================================================================================
5556 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5557 const SMESH::long_array& newIDs)
5558 throw (SALOME::SALOME_Exception)
5563 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5564 if(!elem) return false;
5566 int nbn = newIDs.length();
5568 vector<const SMDS_MeshNode*> aNodes(nbn);
5571 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5574 aNodes[nbn1] = aNode;
5577 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5578 << ide << ", " << newIDs << " )";
5580 MESSAGE("ChangeElementNodes");
5581 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5583 declareMeshModified( /*isReComputeSafe=*/ !res );
5587 SMESH_CATCH( SMESH::throwCorbaException );
5591 //=======================================================================
5593 * \brief Makes a part of the mesh quadratic or bi-quadratic
5595 //=======================================================================
5597 void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d,
5598 CORBA::Boolean theToBiQuad,
5599 SMESH::SMESH_IDSource_ptr theObject)
5600 throw (SALOME::SALOME_Exception)
5603 TIDSortedElemSet elems;
5605 if ( !( elemsOK = CORBA::is_nil( theObject )))
5607 prepareIdSource( theObject );
5608 elemsOK = idSourceToSet( theObject, getMeshDS(), elems,
5609 SMDSAbs_All, /*emptyIfIsMesh=*/true );
5613 if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
5614 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5616 if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
5617 else getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
5619 declareMeshModified( /*isReComputeSafe=*/false );
5622 SMESH_CATCH( SMESH::throwCorbaException );
5625 //=======================================================================
5626 //function : ConvertFromQuadratic
5628 //=======================================================================
5630 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5631 throw (SALOME::SALOME_Exception)
5633 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5634 TPythonDump() << this << ".ConvertFromQuadratic()";
5635 declareMeshModified( /*isReComputeSafe=*/!isDone );
5639 //=======================================================================
5640 //function : ConvertToQuadratic
5642 //=======================================================================
5644 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5645 throw (SALOME::SALOME_Exception)
5647 convertToQuadratic( theForce3d, false );
5648 TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
5651 //================================================================================
5653 * \brief Makes a part of the mesh quadratic
5655 //================================================================================
5657 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5658 SMESH::SMESH_IDSource_ptr theObject)
5659 throw (SALOME::SALOME_Exception)
5661 convertToQuadratic( theForce3d, false, theObject );
5662 TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
5665 //================================================================================
5667 * \brief Makes a part of the mesh bi-quadratic
5669 //================================================================================
5671 void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean theForce3d,
5672 SMESH::SMESH_IDSource_ptr theObject)
5673 throw (SALOME::SALOME_Exception)
5675 convertToQuadratic( theForce3d, true, theObject );
5676 TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
5679 //================================================================================
5681 * \brief Makes a part of the mesh linear
5683 //================================================================================
5685 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5686 throw (SALOME::SALOME_Exception)
5692 TIDSortedElemSet elems;
5693 prepareIdSource( theObject );
5694 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5696 if ( elems.empty() )
5698 ConvertFromQuadratic();
5700 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5702 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5706 getEditor().ConvertFromQuadratic(elems);
5709 declareMeshModified( /*isReComputeSafe=*/false );
5711 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5713 SMESH_CATCH( SMESH::throwCorbaException );
5716 //=======================================================================
5717 //function : makeMesh
5718 //purpose : create a named imported mesh
5719 //=======================================================================
5721 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5723 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5724 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5725 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5726 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5727 gen->SetName( meshSO, theMeshName, "Mesh" );
5728 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5730 return mesh._retn();
5733 //=======================================================================
5734 //function : dumpGroupsList
5736 //=======================================================================
5738 void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPython,
5739 const SMESH::ListOfGroups * theGroupList)
5741 bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
5742 if ( isDumpGroupList )
5743 theDumpPython << theGroupList << " = ";
5746 //================================================================================
5748 \brief Generates the unique group name.
5749 \param thePrefix name prefix
5752 //================================================================================
5754 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5756 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5757 set<string> groupNames;
5759 // Get existing group names
5760 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5761 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5762 if (CORBA::is_nil(aGroup))
5765 CORBA::String_var name = aGroup->GetName();
5766 groupNames.insert( name.in() );
5770 string name = thePrefix;
5773 while (!groupNames.insert(name).second)
5774 name = SMESH_Comment( thePrefix ) << "_" << index++;
5779 //================================================================================
5781 * \brief Prepare SMESH_IDSource for work
5783 //================================================================================
5785 void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
5787 if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5789 SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
5790 filter->SetMesh( mesh );
5794 //================================================================================
5796 * \brief Duplicates given elements, i.e. creates new elements based on the
5797 * same nodes as the given ones.
5798 * \param theElements - container of elements to duplicate.
5799 * \param theGroupName - a name of group to contain the generated elements.
5800 * If a group with such a name already exists, the new elements
5801 * are added to the existng group, else a new group is created.
5802 * If \a theGroupName is empty, new elements are not added
5804 * \return a group where the new elements are added. NULL if theGroupName == "".
5807 //================================================================================
5809 SMESH::SMESH_Group_ptr
5810 SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
5811 const char* theGroupName)
5812 throw (SALOME::SALOME_Exception)
5814 SMESH::SMESH_Group_var newGroup;
5821 TIDSortedElemSet elems;
5822 prepareIdSource( theElements );
5823 if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
5825 getEditor().DoubleElements( elems );
5827 if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
5830 SMESH::ElementType type =
5831 SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
5832 // find existing group
5833 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5834 for ( size_t i = 0; i < groups->length(); ++i )
5835 if ( groups[i]->GetType() == type )
5837 CORBA::String_var name = groups[i]->GetName();
5838 if ( strcmp( name, theGroupName ) == 0 ) {
5839 newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
5843 // create a new group
5844 if ( newGroup->_is_nil() )
5845 newGroup = myMesh_i->CreateGroup( type, theGroupName );
5847 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
5849 SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
5850 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
5851 for ( int i = 1; i <= aSeq.Length(); i++ )
5852 groupDS->SMDSGroup().Add( aSeq(i) );
5857 if ( !newGroup->_is_nil() )
5858 pyDump << newGroup << " = ";
5859 pyDump << this << ".DoubleElements( "
5860 << theElements << ", " << "'" << theGroupName <<"')";
5862 SMESH_CATCH( SMESH::throwCorbaException );
5864 return newGroup._retn();
5867 //================================================================================
5869 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5870 \param theNodes - identifiers of nodes to be doubled
5871 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5872 nodes. If list of element identifiers is empty then nodes are doubled but
5873 they not assigned to elements
5874 \return TRUE if operation has been completed successfully, FALSE otherwise
5875 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5877 //================================================================================
5879 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5880 const SMESH::long_array& theModifiedElems )
5881 throw (SALOME::SALOME_Exception)
5886 list< int > aListOfNodes;
5888 for ( i = 0, n = theNodes.length(); i < n; i++ )
5889 aListOfNodes.push_back( theNodes[ i ] );
5891 list< int > aListOfElems;
5892 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5893 aListOfElems.push_back( theModifiedElems[ i ] );
5895 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
5897 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5899 // Update Python script
5900 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5904 SMESH_CATCH( SMESH::throwCorbaException );
5908 //================================================================================
5910 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5911 This method provided for convenience works as DoubleNodes() described above.
5912 \param theNodeId - identifier of node to be doubled.
5913 \param theModifiedElems - identifiers of elements to be updated.
5914 \return TRUE if operation has been completed successfully, FALSE otherwise
5915 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5917 //================================================================================
5919 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5920 const SMESH::long_array& theModifiedElems )
5921 throw (SALOME::SALOME_Exception)
5924 SMESH::long_array_var aNodes = new SMESH::long_array;
5925 aNodes->length( 1 );
5926 aNodes[ 0 ] = theNodeId;
5928 TPythonDump pyDump; // suppress dump by the next line
5930 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5932 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5936 SMESH_CATCH( SMESH::throwCorbaException );
5940 //================================================================================
5942 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5943 This method provided for convenience works as DoubleNodes() described above.
5944 \param theNodes - group of nodes to be doubled.
5945 \param theModifiedElems - group of elements to be updated.
5946 \return TRUE if operation has been completed successfully, FALSE otherwise
5947 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5949 //================================================================================
5951 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5952 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5953 throw (SALOME::SALOME_Exception)
5956 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5959 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5960 SMESH::long_array_var aModifiedElems;
5961 if ( !CORBA::is_nil( theModifiedElems ) )
5962 aModifiedElems = theModifiedElems->GetListOfID();
5965 aModifiedElems = new SMESH::long_array;
5966 aModifiedElems->length( 0 );
5969 TPythonDump pyDump; // suppress dump by the next line
5971 bool done = DoubleNodes( aNodes, aModifiedElems );
5973 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5977 SMESH_CATCH( SMESH::throwCorbaException );
5981 //================================================================================
5983 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5984 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5985 * \param theNodes - group of nodes to be doubled.
5986 * \param theModifiedElems - group of elements to be updated.
5987 * \return a new group with newly created nodes
5988 * \sa DoubleNodeGroup()
5990 //================================================================================
5992 SMESH::SMESH_Group_ptr
5993 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5994 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5995 throw (SALOME::SALOME_Exception)
5998 SMESH::SMESH_Group_var aNewGroup;
6000 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
6001 return aNewGroup._retn();
6004 SMESH::long_array_var aNodes = theNodes->GetListOfID();
6005 SMESH::long_array_var aModifiedElems;
6006 if ( !CORBA::is_nil( theModifiedElems ) )
6007 aModifiedElems = theModifiedElems->GetListOfID();
6009 aModifiedElems = new SMESH::long_array;
6010 aModifiedElems->length( 0 );
6013 TPythonDump pyDump; // suppress dump by the next line
6015 bool aResult = DoubleNodes( aNodes, aModifiedElems );
6018 // Create group with newly created nodes
6019 SMESH::long_array_var anIds = GetLastCreatedNodes();
6020 if (anIds->length() > 0) {
6021 string anUnindexedName (theNodes->GetName());
6022 string aNewName = generateGroupName(anUnindexedName + "_double");
6023 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6024 aNewGroup->Add(anIds);
6025 pyDump << aNewGroup << " = ";
6029 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
6030 << theModifiedElems << " )";
6032 return aNewGroup._retn();
6034 SMESH_CATCH( SMESH::throwCorbaException );
6038 //================================================================================
6040 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6041 This method provided for convenience works as DoubleNodes() described above.
6042 \param theNodes - list of groups of nodes to be doubled
6043 \param theModifiedElems - list of groups of elements to be updated.
6044 \return TRUE if operation has been completed successfully, FALSE otherwise
6045 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
6047 //================================================================================
6049 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
6050 const SMESH::ListOfGroups& theModifiedElems )
6051 throw (SALOME::SALOME_Exception)
6056 std::list< int > aNodes;
6058 for ( i = 0, n = theNodes.length(); i < n; i++ )
6060 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
6061 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
6063 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6064 for ( j = 0, m = aCurr->length(); j < m; j++ )
6065 aNodes.push_back( aCurr[ j ] );
6069 std::list< int > anElems;
6070 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
6072 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
6073 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
6075 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6076 for ( j = 0, m = aCurr->length(); j < m; j++ )
6077 anElems.push_back( aCurr[ j ] );
6081 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
6083 declareMeshModified( /*isReComputeSafe=*/false );
6085 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
6089 SMESH_CATCH( SMESH::throwCorbaException );
6093 //================================================================================
6095 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6096 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
6097 * \param theNodes - group of nodes to be doubled.
6098 * \param theModifiedElems - group of elements to be updated.
6099 * \return a new group with newly created nodes
6100 * \sa DoubleNodeGroups()
6102 //================================================================================
6104 SMESH::SMESH_Group_ptr
6105 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
6106 const SMESH::ListOfGroups& theModifiedElems )
6107 throw (SALOME::SALOME_Exception)
6109 SMESH::SMESH_Group_var aNewGroup;
6111 TPythonDump pyDump; // suppress dump by the next line
6113 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
6117 // Create group with newly created nodes
6118 SMESH::long_array_var anIds = GetLastCreatedNodes();
6119 if (anIds->length() > 0) {
6120 string anUnindexedName (theNodes[0]->GetName());
6121 string aNewName = generateGroupName(anUnindexedName + "_double");
6122 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6123 aNewGroup->Add(anIds);
6124 pyDump << aNewGroup << " = ";
6128 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
6129 << theModifiedElems << " )";
6131 return aNewGroup._retn();
6135 //================================================================================
6137 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6138 \param theElems - the list of elements (edges or faces) to be replicated
6139 The nodes for duplication could be found from these elements
6140 \param theNodesNot - list of nodes to NOT replicate
6141 \param theAffectedElems - the list of elements (cells and edges) to which the
6142 replicated nodes should be associated to.
6143 \return TRUE if operation has been completed successfully, FALSE otherwise
6144 \sa DoubleNodeGroup(), DoubleNodeGroups()
6146 //================================================================================
6148 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
6149 const SMESH::long_array& theNodesNot,
6150 const SMESH::long_array& theAffectedElems )
6151 throw (SALOME::SALOME_Exception)
6156 SMESHDS_Mesh* aMeshDS = getMeshDS();
6157 TIDSortedElemSet anElems, aNodes, anAffected;
6158 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6159 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6160 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
6162 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6164 // Update Python script
6165 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
6166 << theNodesNot << ", " << theAffectedElems << " )";
6168 declareMeshModified( /*isReComputeSafe=*/false );
6171 SMESH_CATCH( SMESH::throwCorbaException );
6175 //================================================================================
6177 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6178 \param theElems - the list of elements (edges or faces) to be replicated
6179 The nodes for duplication could be found from these elements
6180 \param theNodesNot - list of nodes to NOT replicate
6181 \param theShape - shape to detect affected elements (element which geometric center
6182 located on or inside shape).
6183 The replicated nodes should be associated to affected elements.
6184 \return TRUE if operation has been completed successfully, FALSE otherwise
6185 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
6187 //================================================================================
6189 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
6190 const SMESH::long_array& theNodesNot,
6191 GEOM::GEOM_Object_ptr theShape )
6192 throw (SALOME::SALOME_Exception)
6198 SMESHDS_Mesh* aMeshDS = getMeshDS();
6199 TIDSortedElemSet anElems, aNodes;
6200 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6201 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6203 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6204 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6206 // Update Python script
6207 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
6208 << theNodesNot << ", " << theShape << " )";
6210 declareMeshModified( /*isReComputeSafe=*/false );
6213 SMESH_CATCH( SMESH::throwCorbaException );
6217 //================================================================================
6219 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6220 \param theElems - group of of elements (edges or faces) to be replicated
6221 \param theNodesNot - group of nodes not to replicated
6222 \param theAffectedElems - group of elements to which the replicated nodes
6223 should be associated to.
6224 \return TRUE if operation has been completed successfully, FALSE otherwise
6225 \sa DoubleNodes(), DoubleNodeGroups()
6227 //================================================================================
6230 SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
6231 SMESH::SMESH_GroupBase_ptr theNodesNot,
6232 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6233 throw (SALOME::SALOME_Exception)
6236 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6242 SMESHDS_Mesh* aMeshDS = getMeshDS();
6243 TIDSortedElemSet anElems, aNodes, anAffected;
6244 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6245 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6246 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6248 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6250 // Update Python script
6251 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
6252 << theNodesNot << ", " << theAffectedElems << " )";
6254 declareMeshModified( /*isReComputeSafe=*/false );
6257 SMESH_CATCH( SMESH::throwCorbaException );
6261 //================================================================================
6263 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6264 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6265 * \param theElems - group of of elements (edges or faces) to be replicated
6266 * \param theNodesNot - group of nodes not to replicated
6267 * \param theAffectedElems - group of elements to which the replicated nodes
6268 * should be associated to.
6269 * \return a new group with newly created elements
6270 * \sa DoubleNodeElemGroup()
6272 //================================================================================
6274 SMESH::SMESH_Group_ptr
6275 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
6276 SMESH::SMESH_GroupBase_ptr theNodesNot,
6277 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6278 throw (SALOME::SALOME_Exception)
6281 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
6285 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6286 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6288 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
6290 << theNodesNot << ", "
6291 << theAffectedElems << " )";
6293 return elemGroup._retn();
6296 //================================================================================
6298 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6299 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6300 * \param theElems - group of of elements (edges or faces) to be replicated
6301 * \param theNodesNot - group of nodes not to replicated
6302 * \param theAffectedElems - group of elements to which the replicated nodes
6303 * should be associated to.
6304 * \return a new group with newly created elements
6305 * \sa DoubleNodeElemGroup()
6307 //================================================================================
6309 SMESH::ListOfGroups*
6310 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
6311 SMESH::SMESH_GroupBase_ptr theNodesNot,
6312 SMESH::SMESH_GroupBase_ptr theAffectedElems,
6313 CORBA::Boolean theElemGroupNeeded,
6314 CORBA::Boolean theNodeGroupNeeded)
6315 throw (SALOME::SALOME_Exception)
6318 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6319 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6320 aTwoGroups->length( 2 );
6322 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6323 return aTwoGroups._retn();
6328 SMESHDS_Mesh* aMeshDS = getMeshDS();
6329 TIDSortedElemSet anElems, aNodes, anAffected;
6330 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6331 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6332 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6335 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6337 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6343 // Create group with newly created elements
6344 CORBA::String_var elemGroupName = theElems->GetName();
6345 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6346 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6348 SMESH::long_array_var anIds = GetLastCreatedElems();
6349 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6350 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6351 aNewElemGroup->Add(anIds);
6353 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6355 SMESH::long_array_var anIds = GetLastCreatedNodes();
6356 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6357 aNewNodeGroup->Add(anIds);
6361 // Update Python script
6364 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6365 else pyDump << aNewElemGroup << ", ";
6366 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6367 else pyDump << aNewNodeGroup << " ] = ";
6369 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
6370 << theNodesNot << ", "
6371 << theAffectedElems << ", "
6372 << theElemGroupNeeded << ", "
6373 << theNodeGroupNeeded <<" )";
6375 aTwoGroups[0] = aNewElemGroup._retn();
6376 aTwoGroups[1] = aNewNodeGroup._retn();
6377 return aTwoGroups._retn();
6379 SMESH_CATCH( SMESH::throwCorbaException );
6383 //================================================================================
6385 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6386 \param theElems - group of of elements (edges or faces) to be replicated
6387 \param theNodesNot - group of nodes not to replicated
6388 \param theShape - shape to detect affected elements (element which geometric center
6389 located on or inside shape).
6390 The replicated nodes should be associated to affected elements.
6391 \return TRUE if operation has been completed successfully, FALSE otherwise
6392 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
6394 //================================================================================
6397 SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
6398 SMESH::SMESH_GroupBase_ptr theNodesNot,
6399 GEOM::GEOM_Object_ptr theShape )
6400 throw (SALOME::SALOME_Exception)
6403 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6409 SMESHDS_Mesh* aMeshDS = getMeshDS();
6410 TIDSortedElemSet anElems, aNodes, anAffected;
6411 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6412 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6414 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6415 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6418 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6420 // Update Python script
6421 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
6422 << theNodesNot << ", " << theShape << " )";
6425 SMESH_CATCH( SMESH::throwCorbaException );
6429 //================================================================================
6431 * \brief Re-load elements from a list of groups into a TIDSortedElemSet
6432 * \param [in] theGrpList - groups
6433 * \param [in] theMeshDS - mesh
6434 * \param [out] theElemSet - set of elements
6435 * \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
6437 //================================================================================
6439 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
6440 SMESHDS_Mesh* theMeshDS,
6441 TIDSortedElemSet& theElemSet,
6442 const bool theIsNodeGrp)
6444 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
6446 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
6447 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
6448 : aGrp->GetType() != SMESH::NODE ) )
6450 SMESH::long_array_var anIDs = aGrp->GetIDs();
6451 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
6456 //================================================================================
6458 \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6459 This method provided for convenience works as DoubleNodes() described above.
6460 \param theElems - list of groups of elements (edges or faces) to be replicated
6461 \param theNodesNot - list of groups of nodes not to replicated
6462 \param theAffectedElems - group of elements to which the replicated nodes
6463 should be associated to.
6464 \return TRUE if operation has been completed successfully, FALSE otherwise
6465 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
6467 //================================================================================
6470 SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
6471 const SMESH::ListOfGroups& theNodesNot,
6472 const SMESH::ListOfGroups& theAffectedElems)
6473 throw (SALOME::SALOME_Exception)
6479 SMESHDS_Mesh* aMeshDS = getMeshDS();
6480 TIDSortedElemSet anElems, aNodes, anAffected;
6481 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6482 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6483 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6485 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6487 // Update Python script
6488 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
6489 << &theNodesNot << ", " << &theAffectedElems << " )";
6491 declareMeshModified( /*isReComputeSafe=*/false );
6494 SMESH_CATCH( SMESH::throwCorbaException );
6498 //================================================================================
6500 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6501 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6502 \param theElems - list of groups of elements (edges or faces) to be replicated
6503 \param theNodesNot - list of groups of nodes not to replicated
6504 \param theAffectedElems - group of elements to which the replicated nodes
6505 should be associated to.
6506 * \return a new group with newly created elements
6507 * \sa DoubleNodeElemGroups()
6509 //================================================================================
6511 SMESH::SMESH_Group_ptr
6512 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
6513 const SMESH::ListOfGroups& theNodesNot,
6514 const SMESH::ListOfGroups& theAffectedElems)
6515 throw (SALOME::SALOME_Exception)
6518 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
6522 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6523 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6525 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
6527 << theNodesNot << ", "
6528 << theAffectedElems << " )";
6530 return elemGroup._retn();
6533 //================================================================================
6535 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6536 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6537 \param theElems - list of groups of elements (edges or faces) to be replicated
6538 \param theNodesNot - list of groups of nodes not to replicated
6539 \param theAffectedElems - group of elements to which the replicated nodes
6540 should be associated to.
6541 * \return a new group with newly created elements
6542 * \sa DoubleNodeElemGroups()
6544 //================================================================================
6546 SMESH::ListOfGroups*
6547 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
6548 const SMESH::ListOfGroups& theNodesNot,
6549 const SMESH::ListOfGroups& theAffectedElems,
6550 CORBA::Boolean theElemGroupNeeded,
6551 CORBA::Boolean theNodeGroupNeeded)
6552 throw (SALOME::SALOME_Exception)
6555 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6556 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6557 aTwoGroups->length( 2 );
6562 SMESHDS_Mesh* aMeshDS = getMeshDS();
6563 TIDSortedElemSet anElems, aNodes, anAffected;
6564 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6565 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6566 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6568 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6570 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6575 // Create group with newly created elements
6576 CORBA::String_var elemGroupName = theElems[0]->GetName();
6577 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6578 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6580 SMESH::long_array_var anIds = GetLastCreatedElems();
6581 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6582 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6583 aNewElemGroup->Add(anIds);
6585 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6587 SMESH::long_array_var anIds = GetLastCreatedNodes();
6588 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6589 aNewNodeGroup->Add(anIds);
6593 // Update Python script
6596 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6597 else pyDump << aNewElemGroup << ", ";
6598 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6599 else pyDump << aNewNodeGroup << " ] = ";
6601 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6602 << &theNodesNot << ", "
6603 << &theAffectedElems << ", "
6604 << theElemGroupNeeded << ", "
6605 << theNodeGroupNeeded << " )";
6607 aTwoGroups[0] = aNewElemGroup._retn();
6608 aTwoGroups[1] = aNewNodeGroup._retn();
6609 return aTwoGroups._retn();
6611 SMESH_CATCH( SMESH::throwCorbaException );
6615 //================================================================================
6617 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6618 This method provided for convenience works as DoubleNodes() described above.
6619 \param theElems - list of groups of elements (edges or faces) to be replicated
6620 \param theNodesNot - list of groups of nodes not to replicated
6621 \param theShape - shape to detect affected elements (element which geometric center
6622 located on or inside shape).
6623 The replicated nodes should be associated to affected elements.
6624 \return TRUE if operation has been completed successfully, FALSE otherwise
6625 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6627 //================================================================================
6630 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6631 const SMESH::ListOfGroups& theNodesNot,
6632 GEOM::GEOM_Object_ptr theShape )
6633 throw (SALOME::SALOME_Exception)
6639 SMESHDS_Mesh* aMeshDS = getMeshDS();
6640 TIDSortedElemSet anElems, aNodes;
6641 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6642 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6644 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6645 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6647 // Update Python script
6648 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6649 << &theNodesNot << ", " << theShape << " )";
6651 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6654 SMESH_CATCH( SMESH::throwCorbaException );
6658 //================================================================================
6660 \brief Identify the elements that will be affected by node duplication (actual
6661 duplication is not performed.
6662 This method is the first step of DoubleNodeElemGroupsInRegion.
6663 \param theElems - list of groups of elements (edges or faces) to be replicated
6664 \param theNodesNot - list of groups of nodes not to replicated
6665 \param theShape - shape to detect affected elements (element which geometric center
6666 located on or inside shape).
6667 The replicated nodes should be associated to affected elements.
6668 \return groups of affected elements
6669 \sa DoubleNodeElemGroupsInRegion()
6671 //================================================================================
6672 SMESH::ListOfGroups*
6673 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6674 const SMESH::ListOfGroups& theNodesNot,
6675 GEOM::GEOM_Object_ptr theShape )
6676 throw (SALOME::SALOME_Exception)
6679 MESSAGE("AffectedElemGroupsInRegion");
6680 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6681 bool isEdgeGroup = false;
6682 bool isFaceGroup = false;
6683 bool isVolumeGroup = false;
6684 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6685 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6686 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6690 ::SMESH_MeshEditor aMeshEditor(myMesh);
6692 SMESHDS_Mesh* aMeshDS = getMeshDS();
6693 TIDSortedElemSet anElems, aNodes;
6694 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6695 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6697 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6698 TIDSortedElemSet anAffected;
6699 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6702 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6707 int lg = anAffected.size();
6708 MESSAGE("lg="<< lg);
6709 SMESH::long_array_var volumeIds = new SMESH::long_array;
6710 volumeIds->length(lg);
6711 SMESH::long_array_var faceIds = new SMESH::long_array;
6712 faceIds->length(lg);
6713 SMESH::long_array_var edgeIds = new SMESH::long_array;
6714 edgeIds->length(lg);
6719 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6720 for (; eIt != anAffected.end(); ++eIt)
6722 const SMDS_MeshElement* anElem = *eIt;
6725 int elemId = anElem->GetID();
6726 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6727 volumeIds[ivol++] = elemId;
6728 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6729 faceIds[iface++] = elemId;
6730 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6731 edgeIds[iedge++] = elemId;
6733 volumeIds->length(ivol);
6734 faceIds->length(iface);
6735 edgeIds->length(iedge);
6737 aNewVolumeGroup->Add(volumeIds);
6738 aNewFaceGroup->Add(faceIds);
6739 aNewEdgeGroup->Add(edgeIds);
6740 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6741 isFaceGroup = (aNewFaceGroup->Size() > 0);
6742 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6746 if (isEdgeGroup) nbGroups++;
6747 if (isFaceGroup) nbGroups++;
6748 if (isVolumeGroup) nbGroups++;
6749 aListOfGroups->length(nbGroups);
6752 if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
6753 if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
6754 if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
6756 // Update Python script
6759 if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
6760 if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
6761 if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
6763 pyDump << this << ".AffectedElemGroupsInRegion( "
6764 << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6766 return aListOfGroups._retn();
6768 SMESH_CATCH( SMESH::throwCorbaException );
6772 //================================================================================
6774 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6775 The created 2D mesh elements based on nodes of free faces of boundary volumes
6776 \return TRUE if operation has been completed successfully, FALSE otherwise
6778 //================================================================================
6780 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6781 throw (SALOME::SALOME_Exception)
6786 bool aResult = getEditor().Make2DMeshFrom3D();
6788 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6790 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6793 SMESH_CATCH( SMESH::throwCorbaException );
6797 //================================================================================
6799 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6800 * The list of groups must contain at least two groups. The groups have to be disjoint:
6801 * no common element into two different groups.
6802 * The nodes of the internal faces at the boundaries of the groups are doubled.
6803 * Optionally, the internal faces are replaced by flat elements.
6804 * Triangles are transformed into prisms, and quadrangles into hexahedrons.
6805 * The flat elements are stored in groups of volumes.
6806 * These groups are named according to the position of the group in the list:
6807 * 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.
6808 * 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.
6809 * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
6810 * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
6811 * @param theDomains - list of groups of volumes
6812 * @param createJointElems - if TRUE, create the elements
6813 * @return TRUE if operation has been completed successfully, FALSE otherwise
6815 //================================================================================
6818 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6819 CORBA::Boolean createJointElems )
6820 throw (SALOME::SALOME_Exception)
6822 bool aResult = false;
6827 SMESHDS_Mesh* aMeshDS = getMeshDS();
6829 // MESSAGE("theDomains.length = "<<theDomains.length());
6830 if ( theDomains.length() <= 1 )
6831 THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
6832 vector<TIDSortedElemSet> domains;
6835 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6837 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6838 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6840 // if ( aGrp->GetType() != SMESH::VOLUME )
6841 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6842 TIDSortedElemSet domain;
6844 domains.push_back(domain);
6845 SMESH::long_array_var anIDs = aGrp->GetIDs();
6846 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6850 aResult = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems );
6851 // TODO publish the groups of flat elements in study
6853 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6855 // Update Python script
6856 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6857 << ", " << createJointElems << " )";
6859 SMESH_CATCH( SMESH::throwCorbaException );
6864 //================================================================================
6866 * \brief Double nodes on some external faces and create flat elements.
6867 * Flat elements are mainly used by some types of mechanic calculations.
6869 * Each group of the list must be constituted of faces.
6870 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6871 * @param theGroupsOfFaces - list of groups of faces
6872 * @return TRUE if operation has been completed successfully, FALSE otherwise
6874 //================================================================================
6877 SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6878 throw (SALOME::SALOME_Exception)
6883 SMESHDS_Mesh* aMeshDS = getMeshDS();
6885 vector<TIDSortedElemSet> faceGroups;
6888 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6890 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6891 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6893 TIDSortedElemSet faceGroup;
6895 faceGroups.push_back(faceGroup);
6896 SMESH::long_array_var anIDs = aGrp->GetIDs();
6897 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6901 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
6902 // TODO publish the groups of flat elements in study
6904 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6906 // Update Python script
6907 TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6910 SMESH_CATCH( SMESH::throwCorbaException );
6914 //================================================================================
6916 * \brief Identify all the elements around a geom shape, get the faces delimiting
6919 * Build groups of volume to remove, groups of faces to replace on the skin of the
6920 * object, groups of faces to remove inside the object, (idem edges).
6921 * Build ordered list of nodes at the border of each group of faces to replace
6922 * (to be used to build a geom subshape).
6924 //================================================================================
6926 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6927 GEOM::GEOM_Object_ptr theShape,
6928 const char* groupName,
6929 const SMESH::double_array& theNodesCoords,
6930 SMESH::array_of_long_array_out GroupsOfNodes)
6931 throw (SALOME::SALOME_Exception)
6936 std::vector<std::vector<int> > aListOfListOfNodes;
6937 ::SMESH_MeshEditor aMeshEditor( myMesh );
6939 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
6940 if ( !theNodeSearcher )
6941 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
6943 vector<double> nodesCoords;
6944 for (int i = 0; i < theNodesCoords.length(); i++)
6946 nodesCoords.push_back( theNodesCoords[i] );
6949 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6950 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
6951 nodesCoords, aListOfListOfNodes);
6953 GroupsOfNodes = new SMESH::array_of_long_array;
6954 GroupsOfNodes->length( aListOfListOfNodes.size() );
6955 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
6956 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
6958 vector<int>& aListOfNodes = *llIt;
6959 vector<int>::iterator lIt = aListOfNodes.begin();;
6960 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
6961 aGroup.length( aListOfNodes.size() );
6962 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
6963 aGroup[ j ] = (*lIt);
6965 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
6968 << ", '" << groupName << "', "
6969 << theNodesCoords << " )";
6971 SMESH_CATCH( SMESH::throwCorbaException );
6974 // issue 20749 ===================================================================
6976 * \brief Creates missing boundary elements
6977 * \param elements - elements whose boundary is to be checked
6978 * \param dimension - defines type of boundary elements to create
6979 * \param groupName - a name of group to store created boundary elements in,
6980 * "" means not to create the group
6981 * \param meshName - a name of new mesh to store created boundary elements in,
6982 * "" means not to create the new mesh
6983 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
6984 * \param toCopyExistingBondary - if true, not only new but also pre-existing
6985 * boundary elements will be copied into the new mesh
6986 * \param group - returns the create group, if any
6987 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
6989 // ================================================================================
6991 SMESH::SMESH_Mesh_ptr
6992 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
6993 SMESH::Bnd_Dimension dim,
6994 const char* groupName,
6995 const char* meshName,
6996 CORBA::Boolean toCopyElements,
6997 CORBA::Boolean toCopyExistingBondary,
6998 SMESH::SMESH_Group_out group)
6999 throw (SALOME::SALOME_Exception)
7004 if ( dim > SMESH::BND_1DFROM2D )
7005 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7007 SMESHDS_Mesh* aMeshDS = getMeshDS();
7009 SMESH::SMESH_Mesh_var mesh_var;
7010 SMESH::SMESH_Group_var group_var;
7014 TIDSortedElemSet elements;
7015 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
7016 prepareIdSource( idSource );
7017 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
7021 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
7022 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7024 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
7026 // group of new boundary elements
7027 SMESH_Group* smesh_group = 0;
7028 if ( strlen(groupName) )
7030 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
7031 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7032 smesh_group = group_i->GetSmeshGroup();
7036 getEditor().MakeBoundaryMesh( elements,
7037 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7041 toCopyExistingBondary);
7044 smesh_mesh->GetMeshDS()->Modified();
7047 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7049 // result of MakeBoundaryMesh() is a tuple (mesh, group)
7050 if ( mesh_var->_is_nil() )
7051 pyDump << myMesh_i->_this() << ", ";
7053 pyDump << mesh_var << ", ";
7054 if ( group_var->_is_nil() )
7055 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7057 pyDump << group_var << " = ";
7058 pyDump << this << ".MakeBoundaryMesh( "
7060 << "SMESH." << dimName[int(dim)] << ", "
7061 << "'" << groupName << "', "
7062 << "'" << meshName<< "', "
7063 << toCopyElements << ", "
7064 << toCopyExistingBondary << ")";
7066 group = group_var._retn();
7067 return mesh_var._retn();
7069 SMESH_CATCH( SMESH::throwCorbaException );
7070 return SMESH::SMESH_Mesh::_nil();
7073 //================================================================================
7075 * \brief Creates missing boundary elements
7076 * \param dimension - defines type of boundary elements to create
7077 * \param groupName - a name of group to store all boundary elements in,
7078 * "" means not to create the group
7079 * \param meshName - a name of a new mesh, which is a copy of the initial
7080 * mesh + created boundary elements; "" means not to create the new mesh
7081 * \param toCopyAll - if true, the whole initial mesh will be copied into
7082 * the new mesh else only boundary elements will be copied into the new mesh
7083 * \param groups - optional groups of elements to make boundary around
7084 * \param mesh - returns the mesh where elements were added to
7085 * \param group - returns the created group, if any
7086 * \retval long - number of added boundary elements
7088 //================================================================================
7090 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
7091 const char* groupName,
7092 const char* meshName,
7093 CORBA::Boolean toCopyAll,
7094 const SMESH::ListOfIDSources& groups,
7095 SMESH::SMESH_Mesh_out mesh,
7096 SMESH::SMESH_Group_out group)
7097 throw (SALOME::SALOME_Exception)
7102 if ( dim > SMESH::BND_1DFROM2D )
7103 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7105 // separate groups belonging to this and other mesh
7106 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
7107 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
7108 groupsOfThisMesh->length( groups.length() );
7109 groupsOfOtherMesh->length( groups.length() );
7110 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
7111 for ( int i = 0; i < groups.length(); ++i )
7113 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
7114 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
7115 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
7117 groupsOfThisMesh[ nbGroups++ ] = groups[i];
7118 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
7119 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
7121 groupsOfThisMesh->length( nbGroups );
7122 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
7127 if ( nbGroupsOfOtherMesh > 0 )
7129 // process groups belonging to another mesh
7130 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
7131 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
7132 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
7133 groupsOfOtherMesh, mesh, group );
7136 SMESH::SMESH_Mesh_var mesh_var;
7137 SMESH::SMESH_Group_var group_var;
7140 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
7141 const bool toCopyMesh = ( strlen( meshName ) > 0 );
7145 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
7147 /*toCopyGroups=*/false,
7148 /*toKeepIDs=*/true);
7150 mesh_var = makeMesh(meshName);
7152 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7153 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
7156 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
7157 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
7159 // group of boundary elements
7160 SMESH_Group* smesh_group = 0;
7161 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
7162 if ( strlen(groupName) )
7164 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
7165 group_var = mesh_i->CreateGroup( groupType, groupName );
7166 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7167 smesh_group = group_i->GetSmeshGroup();
7170 TIDSortedElemSet elements;
7172 if ( groups.length() > 0 )
7174 for ( int i = 0; i < nbGroups; ++i )
7177 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
7179 SMESH::Bnd_Dimension bdim =
7180 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
7181 nbAdded += getEditor().MakeBoundaryMesh( elements,
7182 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
7185 /*toCopyElements=*/false,
7186 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7187 /*toAddExistingBondary=*/true,
7188 /*aroundElements=*/true);
7194 nbAdded += getEditor().MakeBoundaryMesh( elements,
7195 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7198 /*toCopyElements=*/false,
7199 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7200 /*toAddExistingBondary=*/true);
7202 tgtMesh->GetMeshDS()->Modified();
7204 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7206 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
7207 pyDump << "nbAdded, ";
7208 if ( mesh_var->_is_nil() )
7209 pyDump << myMesh_i->_this() << ", ";
7211 pyDump << mesh_var << ", ";
7212 if ( group_var->_is_nil() )
7213 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7215 pyDump << group_var << " = ";
7216 pyDump << this << ".MakeBoundaryElements( "
7217 << "SMESH." << dimName[int(dim)] << ", "
7218 << "'" << groupName << "', "
7219 << "'" << meshName<< "', "
7220 << toCopyAll << ", "
7223 mesh = mesh_var._retn();
7224 group = group_var._retn();
7227 SMESH_CATCH( SMESH::throwCorbaException );