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,
281 SMDS_MeshElement::Filter* aFilter = NULL)
283 SMDS_MeshElement::NonNullFilter filter1;
284 SMDS_MeshElement::TypeFilter filter2( aType );
286 if ( aFilter == NULL )
287 aFilter = ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter*) &filter1 : (SMDS_MeshElement::Filter*) &filter2;
289 SMDS_MeshElement::Filter & filter = *aFilter;
291 if ( aType == SMDSAbs_Node )
292 for (int i=0; i<IDs.length(); i++) {
293 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
295 aMap.insert( aMap.end(), elem );
298 for (int i=0; i<IDs.length(); i++) {
299 const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
301 aMap.insert( aMap.end(), elem );
304 //================================================================================
306 * \brief Retrieve elements of given type from SMESH_IDSource
308 //================================================================================
310 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
311 const SMESHDS_Mesh* theMeshDS,
312 TIDSortedElemSet& theElemSet,
313 const SMDSAbs_ElementType theType,
314 const bool emptyIfIsMesh=false)
317 if ( CORBA::is_nil( theIDSource ) )
319 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
322 SMESH::long_array_var anIDs = theIDSource->GetIDs();
323 if ( anIDs->length() == 0 )
325 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
326 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
328 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
329 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
335 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
336 return bool(anIDs->length()) == bool(theElemSet.size());
340 //================================================================================
342 * \brief Retrieve nodes from SMESH_IDSource
344 //================================================================================
346 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
347 const SMESHDS_Mesh* theMeshDS,
348 TIDSortedNodeSet& theNodeSet)
351 if ( CORBA::is_nil( theObject ) )
353 SMESH::array_of_ElementType_var types = theObject->GetTypes();
354 SMESH::long_array_var aElementsId = theObject->GetIDs();
355 if ( types->length() == 1 && types[0] == SMESH::NODE)
357 for(int i = 0; i < aElementsId->length(); i++)
358 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
359 theNodeSet.insert( theNodeSet.end(), n);
361 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
363 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
364 while ( nIt->more( ))
365 if( const SMDS_MeshElement * elem = nIt->next() )
366 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
370 for(int i = 0; i < aElementsId->length(); i++)
371 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
372 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
376 //================================================================================
378 * \brief Returns elements connected to the given elements
380 //================================================================================
382 void getElementsAround(const TIDSortedElemSet& theElements,
383 const SMESHDS_Mesh* theMeshDS,
384 TIDSortedElemSet& theElementsAround)
386 if ( theElements.empty() ) return;
388 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
389 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
391 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
392 return; // all the elements are in theElements
395 elemType = SMDSAbs_All;
397 TIDSortedElemSet visitedNodes;
398 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
399 for ( ; elemIt != theElements.end(); ++elemIt )
401 const SMDS_MeshElement* e = *elemIt;
402 int i = e->NbCornerNodes();
405 const SMDS_MeshNode* n = e->GetNode( i );
406 if ( visitedNodes.insert( n ).second )
408 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
409 while ( invIt->more() )
411 const SMDS_MeshElement* elemAround = invIt->next();
412 if ( !theElements.count( elemAround ))
413 theElementsAround.insert( elemAround );
420 //================================================================================
422 * \brief Return a string used to detect change of mesh part on which theElementSearcher
423 * is going to be used
425 //================================================================================
427 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
429 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
430 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
431 // take into account passible group modification
432 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
433 partIOR += SMESH_Comment( type );
437 } // namespace MeshEditor_I
439 using namespace MeshEditor_I;
441 //=============================================================================
445 //=============================================================================
447 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
449 myMesh( &theMesh->GetImpl() ),
451 myIsPreviewMode ( isPreview ),
457 //================================================================================
461 //================================================================================
463 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
465 PortableServer::POA_var poa = SMESH_Gen_i::GetPOA();
466 PortableServer::ObjectId_var anObjectId = poa->servant_to_id(this);
467 poa->deactivate_object(anObjectId.in());
469 //deleteAuxIDSources();
470 delete myPreviewMesh; myPreviewMesh = 0;
471 delete myPreviewEditor; myPreviewEditor = 0;
474 //================================================================================
476 * \brief Clear members
478 //================================================================================
480 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
482 if ( myIsPreviewMode ) {
483 if ( myPreviewMesh ) myPreviewMesh->RemoveAll();
486 if ( deleteSearchers )
487 TSearchersDeleter::Delete();
489 getEditor().GetError().reset();
490 getEditor().CrearLastCreated();
493 //================================================================================
495 * \brief Increment mesh modif time and optionally record that the performed
496 * modification may influence futher mesh re-compute.
497 * \param [in] isReComputeSafe - true if the modification does not infulence
498 * futher mesh re-compute
500 //================================================================================
502 void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
504 myMesh->GetMeshDS()->Modified();
505 if ( !isReComputeSafe )
506 myMesh->SetIsModified( true );
509 //================================================================================
511 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
512 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
514 //================================================================================
516 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
518 if ( myIsPreviewMode && !myPreviewEditor ) {
519 if ( !myPreviewMesh ) getPreviewMesh();
520 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
522 return myIsPreviewMode ? *myPreviewEditor : myEditor;
525 //================================================================================
527 * \brief Initialize and return myPreviewMesh
528 * \param previewElements - type of elements to show in preview
530 * WARNING: call it once par a method!
532 //================================================================================
534 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
536 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
538 delete myPreviewEditor;
540 delete myPreviewMesh;
541 myPreviewMesh = new TPreviewMesh( previewElements );
543 myPreviewMesh->Clear();
544 return myPreviewMesh;
547 //================================================================================
549 * Return data of mesh edition preview
551 //================================================================================
553 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
554 throw (SALOME::SALOME_Exception)
557 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
559 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
561 list<int> aNodesConnectivity;
562 typedef map<int, int> TNodesMap;
565 SMESHDS_Mesh* aMeshDS;
566 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
568 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
569 aMeshDS = aMeshPartDS.get();
572 aMeshDS = getEditor().GetMeshDS();
574 myPreviewData = new SMESH::MeshPreviewStruct();
575 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
578 SMDSAbs_ElementType previewType = SMDSAbs_All;
580 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
581 previewType = aPreviewMesh->myPreviewType;
582 switch ( previewType ) {
583 case SMDSAbs_Edge : break;
584 case SMDSAbs_Face : break;
585 case SMDSAbs_Volume: break;
587 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
591 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
593 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
595 while ( itMeshElems->more() ) {
596 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
597 SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator();
598 while ( itElemNodes->more() ) {
599 const SMDS_MeshNode* aMeshNode = itElemNodes->next();
600 int aNodeID = aMeshNode->GetID();
601 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
602 if ( anIter == nodesMap.end() ) {
603 // filling the nodes coordinates
604 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
605 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
606 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
607 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
610 aNodesConnectivity.push_back(anIter->second);
613 // filling the elements types
614 SMDSAbs_ElementType aType = aMeshElem->GetType();
615 bool isPoly = aMeshElem->IsPoly();
616 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
617 myPreviewData->elementTypes[i].isPoly = isPoly;
618 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
621 myPreviewData->nodesXYZ.length( j );
623 // filling the elements connectivities
624 list<int>::iterator aConnIter = aNodesConnectivity.begin();
625 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
626 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
627 myPreviewData->elementConnectivities[i] = *aConnIter;
629 return myPreviewData._retn();
631 SMESH_CATCH( SMESH::throwCorbaException );
635 //================================================================================
637 * \brief Returns list of it's IDs of created nodes
638 * \retval SMESH::long_array* - list of node ID
640 //================================================================================
642 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
643 throw (SALOME::SALOME_Exception)
646 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
648 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
649 myLastCreatedNodes->length( aSeq.Length() );
650 for (int i = 1; i <= aSeq.Length(); i++)
651 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
653 return myLastCreatedNodes._retn();
654 SMESH_CATCH( SMESH::throwCorbaException );
658 //================================================================================
660 * \brief Returns list of it's IDs of created elements
661 * \retval SMESH::long_array* - list of elements' ID
663 //================================================================================
665 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
666 throw (SALOME::SALOME_Exception)
669 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
671 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
672 myLastCreatedElems->length( aSeq.Length() );
673 for ( int i = 1; i <= aSeq.Length(); i++ )
674 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
676 return myLastCreatedElems._retn();
677 SMESH_CATCH( SMESH::throwCorbaException );
681 //=======================================================================
682 //function : ClearLastCreated
683 //purpose : Clears sequences of last created elements and nodes
684 //=======================================================================
686 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
689 getEditor().CrearLastCreated();
690 SMESH_CATCH( SMESH::throwCorbaException );
693 //=======================================================================
695 * Returns description of an error/warning occured during the last operation
696 * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
698 //=======================================================================
700 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
701 throw (SALOME::SALOME_Exception)
704 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
705 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
706 if ( errIn && !errIn->IsOK() )
708 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
709 errOut->comment = errIn->myComment.c_str();
710 errOut->subShapeID = -1;
711 errOut->hasBadMesh = !errIn->myBadElements.empty();
716 errOut->subShapeID = -1;
717 errOut->hasBadMesh = false;
720 return errOut._retn();
721 SMESH_CATCH( SMESH::throwCorbaException );
725 //=======================================================================
726 //function : MakeIDSource
727 //purpose : Wrap a sequence of ids in a SMESH_IDSource.
728 // Call UnRegister() as you fininsh using it!!
729 //=======================================================================
731 struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource,
732 public virtual SALOME::GenericObj_i
734 SMESH::long_array _ids;
735 SMESH::ElementType _type;
736 SMESH::SMESH_Mesh_ptr _mesh;
737 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
738 SMESH::long_array* GetMeshInfo() { return 0; }
739 SMESH::long_array* GetNbElementsByType()
741 SMESH::long_array_var aRes = new SMESH::long_array();
742 aRes->length(SMESH::NB_ELEMENT_TYPES);
743 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
744 aRes[ i ] = ( i == _type ) ? _ids.length() : 0;
747 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
748 bool IsMeshInfoCorrect() { return true; }
749 SMESH::array_of_ElementType* GetTypes()
751 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
752 if ( _ids.length() > 0 ) {
756 return types._retn();
760 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
761 SMESH::ElementType type)
763 // if ( myAuxIDSources.size() > 10 ) {
764 // delete myAuxIDSources.front();
765 // myAuxIDSources.pop_front();
768 _IDSource* idSrc = new _IDSource;
769 idSrc->_mesh = myMesh_i->_this();
772 //myAuxIDSources.push_back( idSrc );
774 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
776 return anIDSourceVar._retn();
779 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
781 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
784 CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource,
787 if ( _IDSource* tmpIdSource = SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource ))
789 nbIds = (int) tmpIdSource->_ids.length();
790 return & tmpIdSource->_ids[0];
796 // void SMESH_MeshEditor_i::deleteAuxIDSources()
798 // std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
799 // for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
801 // myAuxIDSources.clear();
804 //=============================================================================
808 //=============================================================================
811 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
812 throw (SALOME::SALOME_Exception)
819 for (int i = 0; i < IDsOfElements.length(); i++)
820 IdList.push_back( IDsOfElements[i] );
822 // Update Python script
823 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
826 bool ret = getEditor().Remove( IdList, false );
828 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
831 SMESH_CATCH( SMESH::throwCorbaException );
835 //=============================================================================
839 //=============================================================================
841 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
842 throw (SALOME::SALOME_Exception)
848 for (int i = 0; i < IDsOfNodes.length(); i++)
849 IdList.push_back( IDsOfNodes[i] );
851 // Update Python script
852 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
854 bool ret = getEditor().Remove( IdList, true );
856 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
859 SMESH_CATCH( SMESH::throwCorbaException );
863 //=============================================================================
867 //=============================================================================
869 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
870 throw (SALOME::SALOME_Exception)
875 // Update Python script
876 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
878 // Create filter to find all orphan nodes
879 SMESH::Controls::Filter::TIdSequence seq;
880 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
881 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
883 // remove orphan nodes (if there are any)
885 for ( int i = 0; i < seq.size(); i++ )
886 IdList.push_back( seq[i] );
888 int nbNodesBefore = myMesh->NbNodes();
889 getEditor().Remove( IdList, true );
890 int nbNodesAfter = myMesh->NbNodes();
892 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
893 return nbNodesBefore - nbNodesAfter;
895 SMESH_CATCH( SMESH::throwCorbaException );
899 //=============================================================================
903 //=============================================================================
905 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
906 throw (SALOME::SALOME_Exception)
911 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
913 // Update Python script
914 TPythonDump() << "nodeID = " << this << ".AddNode( "
915 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
917 declareMeshModified( /*isReComputeSafe=*/false );
920 SMESH_CATCH( SMESH::throwCorbaException );
924 //=============================================================================
926 * Create 0D element on the given node.
928 //=============================================================================
930 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
931 throw (SALOME::SALOME_Exception)
936 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
937 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
939 // Update Python script
940 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
942 declareMeshModified( /*isReComputeSafe=*/false );
944 return elem ? elem->GetID() : 0;
946 SMESH_CATCH( SMESH::throwCorbaException );
950 //=============================================================================
952 * Create a ball element on the given node.
954 //=============================================================================
956 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
957 throw (SALOME::SALOME_Exception)
962 if ( diameter < std::numeric_limits<double>::min() )
963 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
965 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
966 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
968 // Update Python script
969 TPythonDump() << "ballElem = "
970 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
972 declareMeshModified( /*isReComputeSafe=*/false );
973 return elem ? elem->GetID() : 0;
975 SMESH_CATCH( SMESH::throwCorbaException );
979 //=============================================================================
981 * Create an edge, either linear and quadratic (this is determed
982 * by number of given nodes, two or three)
984 //=============================================================================
986 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
987 throw (SALOME::SALOME_Exception)
992 int NbNodes = IDsOfNodes.length();
993 SMDS_MeshElement* elem = 0;
996 CORBA::Long index1 = IDsOfNodes[0];
997 CORBA::Long index2 = IDsOfNodes[1];
998 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
999 getMeshDS()->FindNode(index2));
1001 // Update Python script
1002 TPythonDump() << "edge = " << this << ".AddEdge([ "
1003 << index1 << ", " << index2 <<" ])";
1006 CORBA::Long n1 = IDsOfNodes[0];
1007 CORBA::Long n2 = IDsOfNodes[1];
1008 CORBA::Long n12 = IDsOfNodes[2];
1009 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
1010 getMeshDS()->FindNode(n2),
1011 getMeshDS()->FindNode(n12));
1012 // Update Python script
1013 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
1014 <<n1<<", "<<n2<<", "<<n12<<" ])";
1017 declareMeshModified( /*isReComputeSafe=*/false );
1018 return elem ? elem->GetID() : 0;
1020 SMESH_CATCH( SMESH::throwCorbaException );
1024 //=============================================================================
1028 //=============================================================================
1030 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1031 throw (SALOME::SALOME_Exception)
1036 int NbNodes = IDsOfNodes.length();
1042 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1043 for (int i = 0; i < NbNodes; i++)
1044 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1046 SMDS_MeshElement* elem = 0;
1048 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1049 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1050 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1051 nodes[4], nodes[5]); break;
1052 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1053 nodes[4], nodes[5], nodes[6]); break;
1054 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1055 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1056 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1057 nodes[4], nodes[5], nodes[6], nodes[7],
1059 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1062 // Update Python script
1063 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1065 declareMeshModified( /*isReComputeSafe=*/false );
1067 return elem ? elem->GetID() : 0;
1069 SMESH_CATCH( SMESH::throwCorbaException );
1073 //=============================================================================
1077 //=============================================================================
1078 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1079 throw (SALOME::SALOME_Exception)
1084 int NbNodes = IDsOfNodes.length();
1085 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1086 for (int i = 0; i < NbNodes; i++)
1087 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1089 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1091 // Update Python script
1092 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1094 declareMeshModified( /*isReComputeSafe=*/false );
1095 return elem ? elem->GetID() : 0;
1097 SMESH_CATCH( SMESH::throwCorbaException );
1101 //=============================================================================
1103 * Create volume, either linear and quadratic (this is determed
1104 * by number of given nodes)
1106 //=============================================================================
1108 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1109 throw (SALOME::SALOME_Exception)
1114 int NbNodes = IDsOfNodes.length();
1115 vector< const SMDS_MeshNode*> n(NbNodes);
1116 for(int i=0;i<NbNodes;i++)
1117 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1119 SMDS_MeshElement* elem = 0;
1122 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1123 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1124 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1125 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1126 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1127 n[6],n[7],n[8],n[9]);
1129 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1130 n[6],n[7],n[8],n[9],n[10],n[11]);
1132 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1133 n[7],n[8],n[9],n[10],n[11],n[12]);
1135 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1136 n[9],n[10],n[11],n[12],n[13],n[14]);
1138 case 20: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]);
1142 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1143 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1144 n[15],n[16],n[17],n[18],n[19],
1145 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1149 // Update Python script
1150 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1152 declareMeshModified( /*isReComputeSafe=*/false );
1153 return elem ? elem->GetID() : 0;
1155 SMESH_CATCH( SMESH::throwCorbaException );
1159 //=============================================================================
1161 * AddPolyhedralVolume
1163 //=============================================================================
1164 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1165 const SMESH::long_array & Quantities)
1166 throw (SALOME::SALOME_Exception)
1171 int NbNodes = IDsOfNodes.length();
1172 std::vector<const SMDS_MeshNode*> n (NbNodes);
1173 for (int i = 0; i < NbNodes; i++)
1175 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1176 if (!aNode) return 0;
1180 int NbFaces = Quantities.length();
1181 std::vector<int> q (NbFaces);
1182 for (int j = 0; j < NbFaces; j++)
1183 q[j] = Quantities[j];
1185 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1187 // Update Python script
1188 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1189 << IDsOfNodes << ", " << Quantities << " )";
1191 declareMeshModified( /*isReComputeSafe=*/false );
1192 return elem ? elem->GetID() : 0;
1194 SMESH_CATCH( SMESH::throwCorbaException );
1198 //=============================================================================
1200 * AddPolyhedralVolumeByFaces
1202 //=============================================================================
1204 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1205 throw (SALOME::SALOME_Exception)
1210 int NbFaces = IdsOfFaces.length();
1211 std::vector<const SMDS_MeshNode*> poly_nodes;
1212 std::vector<int> quantities (NbFaces);
1214 for (int i = 0; i < NbFaces; i++) {
1215 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1216 quantities[i] = aFace->NbNodes();
1218 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1219 while (It->more()) {
1220 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1224 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1226 // Update Python script
1227 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1228 << IdsOfFaces << " )";
1230 declareMeshModified( /*isReComputeSafe=*/false );
1231 return elem ? elem->GetID() : 0;
1233 SMESH_CATCH( SMESH::throwCorbaException );
1237 //=============================================================================
1239 // \brief Create 0D elements on all nodes of the given object except those
1240 // nodes on which a 0D element already exists.
1241 // \param theObject object on whose nodes 0D elements will be created.
1242 // \param theGroupName optional name of a group to add 0D elements created
1243 // and/or found on nodes of \a theObject.
1244 // \return an object (a new group or a temporary SMESH_IDSource) holding
1245 // ids of new and/or found 0D elements.
1247 //=============================================================================
1249 SMESH::SMESH_IDSource_ptr
1250 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1251 const char* theGroupName)
1252 throw (SALOME::SALOME_Exception)
1257 SMESH::SMESH_IDSource_var result;
1260 TIDSortedElemSet elements, elems0D;
1261 prepareIdSource( theObject );
1262 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1263 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1265 SMESH::long_array_var newElems = new SMESH::long_array;
1266 newElems->length( elems0D.size() );
1267 TIDSortedElemSet::iterator eIt = elems0D.begin();
1268 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1269 newElems[ i ] = (*eIt)->GetID();
1271 SMESH::SMESH_GroupBase_var groupToFill;
1272 if ( theGroupName && strlen( theGroupName ))
1274 // Get existing group named theGroupName
1275 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1276 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1277 SMESH::SMESH_GroupBase_var group = groups[i];
1278 if ( !group->_is_nil() ) {
1279 CORBA::String_var name = group->GetName();
1280 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1281 groupToFill = group;
1286 if ( groupToFill->_is_nil() )
1287 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1288 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1289 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1292 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1294 group_i->Add( newElems );
1295 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1296 pyDump << groupToFill;
1300 result = MakeIDSource( newElems, SMESH::ELEM0D );
1301 pyDump << "elem0DIDs";
1304 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1305 << theObject << ", '" << theGroupName << "' )";
1307 return result._retn();
1309 SMESH_CATCH( SMESH::throwCorbaException );
1313 //=============================================================================
1315 * \brief Bind a node to a vertex
1316 * \param NodeID - node ID
1317 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1318 * \retval boolean - false if NodeID or VertexID is invalid
1320 //=============================================================================
1322 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1323 throw (SALOME::SALOME_Exception)
1327 SMESHDS_Mesh * mesh = getMeshDS();
1328 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1330 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1332 if ( mesh->MaxShapeIndex() < VertexID )
1333 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1335 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1336 if ( shape.ShapeType() != TopAbs_VERTEX )
1337 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1339 mesh->SetNodeOnVertex( node, VertexID );
1341 myMesh->SetIsModified( true );
1343 SMESH_CATCH( SMESH::throwCorbaException );
1346 //=============================================================================
1348 * \brief Store node position on an edge
1349 * \param NodeID - node ID
1350 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1351 * \param paramOnEdge - parameter on edge where the node is located
1352 * \retval boolean - false if any parameter is invalid
1354 //=============================================================================
1356 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1357 CORBA::Double paramOnEdge)
1358 throw (SALOME::SALOME_Exception)
1362 SMESHDS_Mesh * mesh = getMeshDS();
1363 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1365 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1367 if ( mesh->MaxShapeIndex() < EdgeID )
1368 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1370 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1371 if ( shape.ShapeType() != TopAbs_EDGE )
1372 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1375 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1376 if ( paramOnEdge < f || paramOnEdge > l )
1377 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1379 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1381 myMesh->SetIsModified( true );
1383 SMESH_CATCH( SMESH::throwCorbaException );
1386 //=============================================================================
1388 * \brief Store node position on a face
1389 * \param NodeID - node ID
1390 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1391 * \param u - U parameter on face where the node is located
1392 * \param v - V parameter on face where the node is located
1393 * \retval boolean - false if any parameter is invalid
1395 //=============================================================================
1397 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1398 CORBA::Double u, CORBA::Double v)
1399 throw (SALOME::SALOME_Exception)
1402 SMESHDS_Mesh * mesh = getMeshDS();
1403 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1405 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1407 if ( mesh->MaxShapeIndex() < FaceID )
1408 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1410 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1411 if ( shape.ShapeType() != TopAbs_FACE )
1412 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1414 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1415 bool isOut = ( u < surf.FirstUParameter() ||
1416 u > surf.LastUParameter() ||
1417 v < surf.FirstVParameter() ||
1418 v > surf.LastVParameter() );
1422 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1423 << " u( " << surf.FirstUParameter()
1424 << "," << surf.LastUParameter()
1425 << ") v( " << surf.FirstVParameter()
1426 << "," << surf.LastVParameter() << ")" );
1428 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1431 mesh->SetNodeOnFace( node, FaceID, u, v );
1432 myMesh->SetIsModified( true );
1434 SMESH_CATCH( SMESH::throwCorbaException );
1437 //=============================================================================
1439 * \brief Bind a node to a solid
1440 * \param NodeID - node ID
1441 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1442 * \retval boolean - false if NodeID or SolidID is invalid
1444 //=============================================================================
1446 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1447 throw (SALOME::SALOME_Exception)
1450 SMESHDS_Mesh * mesh = getMeshDS();
1451 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1453 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1455 if ( mesh->MaxShapeIndex() < SolidID )
1456 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1458 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1459 if ( shape.ShapeType() != TopAbs_SOLID &&
1460 shape.ShapeType() != TopAbs_SHELL)
1461 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1463 mesh->SetNodeInVolume( node, SolidID );
1465 SMESH_CATCH( SMESH::throwCorbaException );
1468 //=============================================================================
1470 * \brief Bind an element to a shape
1471 * \param ElementID - element ID
1472 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1474 //=============================================================================
1476 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1477 CORBA::Long ShapeID)
1478 throw (SALOME::SALOME_Exception)
1481 SMESHDS_Mesh * mesh = getMeshDS();
1482 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1484 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1486 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1487 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1489 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1490 if ( shape.ShapeType() != TopAbs_EDGE &&
1491 shape.ShapeType() != TopAbs_FACE &&
1492 shape.ShapeType() != TopAbs_SOLID &&
1493 shape.ShapeType() != TopAbs_SHELL )
1494 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1496 mesh->SetMeshElementOnShape( elem, ShapeID );
1498 myMesh->SetIsModified( true );
1500 SMESH_CATCH( SMESH::throwCorbaException );
1503 //=============================================================================
1507 //=============================================================================
1509 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1510 CORBA::Long NodeID2)
1511 throw (SALOME::SALOME_Exception)
1516 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1517 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1521 // Update Python script
1522 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1523 << NodeID1 << ", " << NodeID2 << " )";
1525 int ret = getEditor().InverseDiag ( n1, n2 );
1527 declareMeshModified( /*isReComputeSafe=*/false );
1530 SMESH_CATCH( SMESH::throwCorbaException );
1534 //=============================================================================
1538 //=============================================================================
1540 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1541 CORBA::Long NodeID2)
1542 throw (SALOME::SALOME_Exception)
1547 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1548 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1552 // Update Python script
1553 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1554 << NodeID1 << ", " << NodeID2 << " )";
1557 bool stat = getEditor().DeleteDiag ( n1, n2 );
1559 declareMeshModified( /*isReComputeSafe=*/!stat );
1563 SMESH_CATCH( SMESH::throwCorbaException );
1567 //=============================================================================
1571 //=============================================================================
1573 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1574 throw (SALOME::SALOME_Exception)
1579 for (int i = 0; i < IDsOfElements.length(); i++)
1581 CORBA::Long index = IDsOfElements[i];
1582 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1584 getEditor().Reorient( elem );
1586 // Update Python script
1587 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1589 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1592 SMESH_CATCH( SMESH::throwCorbaException );
1596 //=============================================================================
1600 //=============================================================================
1602 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1603 throw (SALOME::SALOME_Exception)
1608 TPythonDump aTPythonDump; // suppress dump in Reorient()
1610 prepareIdSource( theObject );
1612 SMESH::long_array_var anElementsId = theObject->GetIDs();
1613 CORBA::Boolean isDone = Reorient(anElementsId);
1615 // Update Python script
1616 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1618 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1621 SMESH_CATCH( SMESH::throwCorbaException );
1625 //=======================================================================
1626 //function : Reorient2D
1627 //purpose : Reorient faces contained in \a the2Dgroup.
1628 // the2Dgroup - the mesh or its part to reorient
1629 // theDirection - desired direction of normal of \a theFace
1630 // theFace - ID of face whose orientation is checked.
1631 // It can be < 1 then \a thePoint is used to find a face.
1632 // thePoint - is used to find a face if \a theFace < 1.
1633 // return number of reoriented elements.
1634 //=======================================================================
1636 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1637 const SMESH::DirStruct& theDirection,
1638 CORBA::Long theFace,
1639 const SMESH::PointStruct& thePoint)
1640 throw (SALOME::SALOME_Exception)
1643 initData(/*deleteSearchers=*/false);
1645 TIDSortedElemSet elements;
1646 prepareIdSource( the2Dgroup );
1647 if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
1648 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1651 const SMDS_MeshElement* face = 0;
1654 face = getMeshDS()->FindElement( theFace );
1656 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1657 if ( face->GetType() != SMDSAbs_Face )
1658 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1662 // create theElementSearcher if needed
1663 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1664 if ( !theElementSearcher )
1666 if ( elements.empty() ) // search in the whole mesh
1668 if ( myMesh->NbFaces() == 0 )
1669 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1671 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1675 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1676 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1678 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1682 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1683 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1686 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1687 if ( !elements.empty() && !elements.count( face ))
1688 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1691 const SMESH::PointStruct * P = &theDirection.PS;
1692 gp_Vec dirVec( P->x, P->y, P->z );
1693 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1694 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1696 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1699 declareMeshModified( /*isReComputeSafe=*/false );
1701 TPythonDump() << this << ".Reorient2D( "
1702 << the2Dgroup << ", "
1703 << theDirection << ", "
1705 << thePoint << " )";
1709 SMESH_CATCH( SMESH::throwCorbaException );
1713 //=============================================================================
1715 * \brief Fuse neighbour triangles into quadrangles.
1717 //=============================================================================
1719 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1720 SMESH::NumericalFunctor_ptr Criterion,
1721 CORBA::Double MaxAngle)
1722 throw (SALOME::SALOME_Exception)
1727 SMESHDS_Mesh* aMesh = getMeshDS();
1728 TIDSortedElemSet faces,copyFaces;
1729 SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE);
1730 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter);
1731 TIDSortedElemSet* workElements = & faces;
1733 if ( myIsPreviewMode ) {
1734 SMDSAbs_ElementType select = SMDSAbs_Face;
1735 getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select );
1736 workElements = & copyFaces;
1739 SMESH::NumericalFunctor_i* aNumericalFunctor =
1740 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1741 SMESH::Controls::NumericalFunctorPtr aCrit;
1742 if ( !aNumericalFunctor )
1743 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1745 aCrit = aNumericalFunctor->GetNumericalFunctor();
1747 if ( !myIsPreviewMode ) {
1748 // Update Python script
1749 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1750 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1753 bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle );
1755 declareMeshModified( /*isReComputeSafe=*/!stat );
1758 SMESH_CATCH( SMESH::throwCorbaException );
1762 //=============================================================================
1764 * \brief Fuse neighbour triangles into quadrangles.
1766 //=============================================================================
1768 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1769 SMESH::NumericalFunctor_ptr Criterion,
1770 CORBA::Double MaxAngle)
1771 throw (SALOME::SALOME_Exception)
1776 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1778 prepareIdSource( theObject );
1779 SMESH::long_array_var anElementsId = theObject->GetIDs();
1780 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1782 if ( !myIsPreviewMode ) {
1783 SMESH::NumericalFunctor_i* aNumericalFunctor =
1784 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1786 // Update Python script
1787 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1788 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1793 SMESH_CATCH( SMESH::throwCorbaException );
1797 //=============================================================================
1799 * \brief Split quadrangles into triangles.
1801 //=============================================================================
1803 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1804 SMESH::NumericalFunctor_ptr Criterion)
1805 throw (SALOME::SALOME_Exception)
1810 SMESHDS_Mesh* aMesh = getMeshDS();
1811 TIDSortedElemSet faces;
1812 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1814 SMESH::NumericalFunctor_i* aNumericalFunctor =
1815 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1816 SMESH::Controls::NumericalFunctorPtr aCrit;
1817 if ( !aNumericalFunctor )
1818 aCrit.reset( new SMESH::Controls::AspectRatio() );
1820 aCrit = aNumericalFunctor->GetNumericalFunctor();
1823 // Update Python script
1824 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1826 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1828 declareMeshModified( /*isReComputeSafe=*/false );
1831 SMESH_CATCH( SMESH::throwCorbaException );
1835 //=============================================================================
1837 * \brief Split quadrangles into triangles.
1839 //=============================================================================
1841 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1842 SMESH::NumericalFunctor_ptr Criterion)
1843 throw (SALOME::SALOME_Exception)
1848 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1850 prepareIdSource( theObject );
1851 SMESH::long_array_var anElementsId = theObject->GetIDs();
1852 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1854 SMESH::NumericalFunctor_i* aNumericalFunctor =
1855 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1857 // Update Python script
1858 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1860 declareMeshModified( /*isReComputeSafe=*/false );
1863 SMESH_CATCH( SMESH::throwCorbaException );
1867 //================================================================================
1869 * \brief Split each of quadrangles into 4 triangles.
1870 * \param [in] theObject - theQuads Container of quadrangles to split.
1872 //================================================================================
1874 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1875 throw (SALOME::SALOME_Exception)
1880 TIDSortedElemSet faces;
1881 prepareIdSource( theObject );
1882 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1884 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1886 getEditor().QuadTo4Tri( faces );
1887 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1889 SMESH_CATCH( SMESH::throwCorbaException );
1892 //=============================================================================
1894 * \brief Split quadrangles into triangles.
1896 //=============================================================================
1898 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1899 CORBA::Boolean Diag13)
1900 throw (SALOME::SALOME_Exception)
1905 SMESHDS_Mesh* aMesh = getMeshDS();
1906 TIDSortedElemSet faces;
1907 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1909 // Update Python script
1910 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1911 << IDsOfElements << ", " << Diag13 << " )";
1913 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1915 declareMeshModified( /*isReComputeSafe=*/ !stat );
1918 SMESH_CATCH( SMESH::throwCorbaException );
1922 //=============================================================================
1924 * \brief Split quadrangles into triangles.
1926 //=============================================================================
1928 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1929 CORBA::Boolean Diag13)
1930 throw (SALOME::SALOME_Exception)
1935 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1937 prepareIdSource( theObject );
1938 SMESH::long_array_var anElementsId = theObject->GetIDs();
1939 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1941 // Update Python script
1942 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1943 << theObject << ", " << Diag13 << " )";
1945 declareMeshModified( /*isReComputeSafe=*/!isDone );
1948 SMESH_CATCH( SMESH::throwCorbaException );
1953 //=============================================================================
1955 * Find better splitting of the given quadrangle.
1956 * \param IDOfQuad ID of the quadrangle to be splitted.
1957 * \param Criterion A criterion to choose a diagonal for splitting.
1958 * \return 1 if 1-3 diagonal is better, 2 if 2-4
1959 * diagonal is better, 0 if error occurs.
1961 //=============================================================================
1963 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1964 SMESH::NumericalFunctor_ptr Criterion)
1965 throw (SALOME::SALOME_Exception)
1970 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
1971 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1973 SMESH::NumericalFunctor_i* aNumericalFunctor =
1974 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1975 SMESH::Controls::NumericalFunctorPtr aCrit;
1976 if (aNumericalFunctor)
1977 aCrit = aNumericalFunctor->GetNumericalFunctor();
1979 aCrit.reset(new SMESH::Controls::AspectRatio());
1981 int id = getEditor().BestSplit(quad, aCrit);
1982 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
1986 SMESH_CATCH( SMESH::throwCorbaException );
1990 //================================================================================
1992 * \brief Split volumic elements into tetrahedrons
1994 //================================================================================
1996 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1997 CORBA::Short methodFlags)
1998 throw (SALOME::SALOME_Exception)
2003 prepareIdSource( elems );
2004 SMESH::long_array_var anElementsId = elems->GetIDs();
2005 TIDSortedElemSet elemSet;
2006 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume );
2008 getEditor().SplitVolumesIntoTetra( elemSet, int( methodFlags ));
2009 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2011 TPythonDump() << this << ".SplitVolumesIntoTetra( "
2012 << elems << ", " << methodFlags << " )";
2014 SMESH_CATCH( SMESH::throwCorbaException );
2017 //=======================================================================
2020 //=======================================================================
2023 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2024 const SMESH::long_array & IDsOfFixedNodes,
2025 CORBA::Long MaxNbOfIterations,
2026 CORBA::Double MaxAspectRatio,
2027 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2028 throw (SALOME::SALOME_Exception)
2030 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2031 MaxAspectRatio, Method, false );
2035 //=======================================================================
2036 //function : SmoothParametric
2038 //=======================================================================
2041 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2042 const SMESH::long_array & IDsOfFixedNodes,
2043 CORBA::Long MaxNbOfIterations,
2044 CORBA::Double MaxAspectRatio,
2045 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2046 throw (SALOME::SALOME_Exception)
2048 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2049 MaxAspectRatio, Method, true );
2053 //=======================================================================
2054 //function : SmoothObject
2056 //=======================================================================
2059 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2060 const SMESH::long_array & IDsOfFixedNodes,
2061 CORBA::Long MaxNbOfIterations,
2062 CORBA::Double MaxAspectRatio,
2063 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2064 throw (SALOME::SALOME_Exception)
2066 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2067 MaxAspectRatio, Method, false);
2071 //=======================================================================
2072 //function : SmoothParametricObject
2074 //=======================================================================
2077 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2078 const SMESH::long_array & IDsOfFixedNodes,
2079 CORBA::Long MaxNbOfIterations,
2080 CORBA::Double MaxAspectRatio,
2081 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2082 throw (SALOME::SALOME_Exception)
2084 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2085 MaxAspectRatio, Method, true);
2089 //=============================================================================
2093 //=============================================================================
2096 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2097 const SMESH::long_array & IDsOfFixedNodes,
2098 CORBA::Long MaxNbOfIterations,
2099 CORBA::Double MaxAspectRatio,
2100 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2102 throw (SALOME::SALOME_Exception)
2107 SMESHDS_Mesh* aMesh = getMeshDS();
2109 TIDSortedElemSet elements;
2110 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2112 set<const SMDS_MeshNode*> fixedNodes;
2113 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
2114 CORBA::Long index = IDsOfFixedNodes[i];
2115 const SMDS_MeshNode * node = aMesh->FindNode(index);
2117 fixedNodes.insert( node );
2119 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2120 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2121 method = ::SMESH_MeshEditor::CENTROIDAL;
2123 getEditor().Smooth(elements, fixedNodes, method,
2124 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2126 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2128 // Update Python script
2129 TPythonDump() << "isDone = " << this << "."
2130 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2131 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2132 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2133 << "SMESH.SMESH_MeshEditor."
2134 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2135 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2139 SMESH_CATCH( SMESH::throwCorbaException );
2143 //=============================================================================
2147 //=============================================================================
2150 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2151 const SMESH::long_array & IDsOfFixedNodes,
2152 CORBA::Long MaxNbOfIterations,
2153 CORBA::Double MaxAspectRatio,
2154 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2156 throw (SALOME::SALOME_Exception)
2161 TPythonDump aTPythonDump; // suppress dump in smooth()
2163 prepareIdSource( theObject );
2164 SMESH::long_array_var anElementsId = theObject->GetIDs();
2165 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2166 MaxAspectRatio, Method, IsParametric);
2168 // Update Python script
2169 aTPythonDump << "isDone = " << this << "."
2170 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2171 << theObject << ", " << IDsOfFixedNodes << ", "
2172 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2173 << "SMESH.SMESH_MeshEditor."
2174 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2175 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2179 SMESH_CATCH( SMESH::throwCorbaException );
2183 //=============================================================================
2187 //=============================================================================
2189 void SMESH_MeshEditor_i::RenumberNodes()
2190 throw (SALOME::SALOME_Exception)
2193 // Update Python script
2194 TPythonDump() << this << ".RenumberNodes()";
2196 getMeshDS()->Renumber( true );
2198 SMESH_CATCH( SMESH::throwCorbaException );
2201 //=============================================================================
2205 //=============================================================================
2207 void SMESH_MeshEditor_i::RenumberElements()
2208 throw (SALOME::SALOME_Exception)
2211 // Update Python script
2212 TPythonDump() << this << ".RenumberElements()";
2214 getMeshDS()->Renumber( false );
2216 SMESH_CATCH( SMESH::throwCorbaException );
2219 //=======================================================================
2221 * \brief Return groups by their IDs
2223 //=======================================================================
2225 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2226 throw (SALOME::SALOME_Exception)
2231 myMesh_i->CreateGroupServants();
2232 return myMesh_i->GetGroups( *groupIDs );
2234 SMESH_CATCH( SMESH::throwCorbaException );
2238 //=======================================================================
2239 //function : rotationSweep
2241 //=======================================================================
2243 SMESH::ListOfGroups*
2244 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2245 const SMESH::AxisStruct & theAxis,
2246 CORBA::Double theAngleInRadians,
2247 CORBA::Long theNbOfSteps,
2248 CORBA::Double theTolerance,
2249 const bool theMakeGroups,
2250 const SMDSAbs_ElementType theElementType)
2251 throw (SALOME::SALOME_Exception)
2256 TIDSortedElemSet inElements, copyElements;
2257 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2259 TIDSortedElemSet* workElements = & inElements;
2260 bool makeWalls=true;
2261 if ( myIsPreviewMode )
2263 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2264 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2265 workElements = & copyElements;
2266 //makeWalls = false;
2269 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2270 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2272 ::SMESH_MeshEditor::PGroupIDs groupIds =
2273 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2274 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2276 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2278 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2280 SMESH_CATCH( SMESH::throwCorbaException );
2284 //=======================================================================
2285 //function : RotationSweep
2287 //=======================================================================
2289 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2290 const SMESH::AxisStruct & theAxis,
2291 CORBA::Double theAngleInRadians,
2292 CORBA::Long theNbOfSteps,
2293 CORBA::Double theTolerance)
2294 throw (SALOME::SALOME_Exception)
2296 if ( !myIsPreviewMode ) {
2297 TPythonDump() << this << ".RotationSweep( "
2298 << theIDsOfElements << ", "
2300 << TVar( theAngleInRadians ) << ", "
2301 << TVar( theNbOfSteps ) << ", "
2302 << TVar( theTolerance ) << " )";
2304 rotationSweep(theIDsOfElements,
2312 //=======================================================================
2313 //function : RotationSweepMakeGroups
2315 //=======================================================================
2317 SMESH::ListOfGroups*
2318 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2319 const SMESH::AxisStruct& theAxis,
2320 CORBA::Double theAngleInRadians,
2321 CORBA::Long theNbOfSteps,
2322 CORBA::Double theTolerance)
2323 throw (SALOME::SALOME_Exception)
2325 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2327 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2333 if (!myIsPreviewMode) {
2334 dumpGroupsList(aPythonDump, aGroups);
2335 aPythonDump << this << ".RotationSweepMakeGroups( "
2336 << theIDsOfElements << ", "
2338 << TVar( theAngleInRadians ) << ", "
2339 << TVar( theNbOfSteps ) << ", "
2340 << TVar( theTolerance ) << " )";
2345 //=======================================================================
2346 //function : RotationSweepObject
2348 //=======================================================================
2350 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2351 const SMESH::AxisStruct & theAxis,
2352 CORBA::Double theAngleInRadians,
2353 CORBA::Long theNbOfSteps,
2354 CORBA::Double theTolerance)
2355 throw (SALOME::SALOME_Exception)
2357 if ( !myIsPreviewMode ) {
2358 TPythonDump() << this << ".RotationSweepObject( "
2359 << theObject << ", "
2361 << theAngleInRadians << ", "
2362 << theNbOfSteps << ", "
2363 << theTolerance << " )";
2365 prepareIdSource( theObject );
2366 SMESH::long_array_var anElementsId = theObject->GetIDs();
2367 rotationSweep(anElementsId,
2375 //=======================================================================
2376 //function : RotationSweepObject1D
2378 //=======================================================================
2380 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2381 const SMESH::AxisStruct & theAxis,
2382 CORBA::Double theAngleInRadians,
2383 CORBA::Long theNbOfSteps,
2384 CORBA::Double theTolerance)
2385 throw (SALOME::SALOME_Exception)
2387 if ( !myIsPreviewMode ) {
2388 TPythonDump() << this << ".RotationSweepObject1D( "
2389 << theObject << ", "
2391 << TVar( theAngleInRadians ) << ", "
2392 << TVar( theNbOfSteps ) << ", "
2393 << TVar( theTolerance ) << " )";
2395 prepareIdSource( theObject );
2396 SMESH::long_array_var anElementsId = theObject->GetIDs();
2397 rotationSweep(anElementsId,
2406 //=======================================================================
2407 //function : RotationSweepObject2D
2409 //=======================================================================
2411 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2412 const SMESH::AxisStruct & theAxis,
2413 CORBA::Double theAngleInRadians,
2414 CORBA::Long theNbOfSteps,
2415 CORBA::Double theTolerance)
2416 throw (SALOME::SALOME_Exception)
2418 if ( !myIsPreviewMode ) {
2419 TPythonDump() << this << ".RotationSweepObject2D( "
2420 << theObject << ", "
2422 << TVar( theAngleInRadians ) << ", "
2423 << TVar( theNbOfSteps ) << ", "
2424 << TVar( theTolerance ) << " )";
2426 prepareIdSource( theObject );
2427 SMESH::long_array_var anElementsId = theObject->GetIDs();
2428 rotationSweep(anElementsId,
2437 //=======================================================================
2438 //function : RotationSweepObjectMakeGroups
2440 //=======================================================================
2442 SMESH::ListOfGroups*
2443 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2444 const SMESH::AxisStruct& theAxis,
2445 CORBA::Double theAngleInRadians,
2446 CORBA::Long theNbOfSteps,
2447 CORBA::Double theTolerance)
2448 throw (SALOME::SALOME_Exception)
2450 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2452 prepareIdSource( theObject );
2453 SMESH::long_array_var anElementsId = theObject->GetIDs();
2454 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2460 if (!myIsPreviewMode) {
2461 dumpGroupsList(aPythonDump, aGroups);
2462 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2463 << theObject << ", "
2465 << theAngleInRadians << ", "
2466 << theNbOfSteps << ", "
2467 << theTolerance << " )";
2472 //=======================================================================
2473 //function : RotationSweepObject1DMakeGroups
2475 //=======================================================================
2477 SMESH::ListOfGroups*
2478 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2479 const SMESH::AxisStruct& theAxis,
2480 CORBA::Double theAngleInRadians,
2481 CORBA::Long theNbOfSteps,
2482 CORBA::Double theTolerance)
2483 throw (SALOME::SALOME_Exception)
2485 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2487 prepareIdSource( theObject );
2488 SMESH::long_array_var anElementsId = theObject->GetIDs();
2489 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2496 if (!myIsPreviewMode) {
2497 dumpGroupsList(aPythonDump, aGroups);
2498 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2499 << theObject << ", "
2501 << TVar( theAngleInRadians ) << ", "
2502 << TVar( theNbOfSteps ) << ", "
2503 << TVar( theTolerance ) << " )";
2508 //=======================================================================
2509 //function : RotationSweepObject2DMakeGroups
2511 //=======================================================================
2513 SMESH::ListOfGroups*
2514 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2515 const SMESH::AxisStruct& theAxis,
2516 CORBA::Double theAngleInRadians,
2517 CORBA::Long theNbOfSteps,
2518 CORBA::Double theTolerance)
2519 throw (SALOME::SALOME_Exception)
2521 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2523 prepareIdSource( theObject );
2524 SMESH::long_array_var anElementsId = theObject->GetIDs();
2525 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2532 if (!myIsPreviewMode) {
2533 dumpGroupsList(aPythonDump, aGroups);
2534 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2535 << theObject << ", "
2537 << TVar( theAngleInRadians ) << ", "
2538 << TVar( theNbOfSteps ) << ", "
2539 << TVar( theTolerance ) << " )";
2545 //=======================================================================
2546 //function : extrusionSweep
2548 //=======================================================================
2550 SMESH::ListOfGroups*
2551 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2552 const SMESH::DirStruct & theStepVector,
2553 CORBA::Long theNbOfSteps,
2555 const SMDSAbs_ElementType theElementType)
2556 throw (SALOME::SALOME_Exception)
2561 TIDSortedElemSet elements, copyElements;
2562 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2564 const SMESH::PointStruct * P = &theStepVector.PS;
2565 gp_Vec stepVec( P->x, P->y, P->z );
2567 TIDSortedElemSet* workElements = & elements;
2569 SMDSAbs_ElementType aType = SMDSAbs_Face;
2570 if (theElementType == SMDSAbs_Node)
2572 aType = SMDSAbs_Edge;
2574 if ( myIsPreviewMode ) {
2575 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2576 getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
2577 workElements = & copyElements;
2578 theMakeGroups = false;
2581 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2582 ::SMESH_MeshEditor::PGroupIDs groupIds =
2583 getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2585 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2587 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2589 SMESH_CATCH( SMESH::throwCorbaException );
2593 //=======================================================================
2594 //function : ExtrusionSweep
2596 //=======================================================================
2598 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2599 const SMESH::DirStruct & theStepVector,
2600 CORBA::Long theNbOfSteps)
2601 throw (SALOME::SALOME_Exception)
2603 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2604 if (!myIsPreviewMode) {
2605 TPythonDump() << this << ".ExtrusionSweep( "
2606 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2610 //=======================================================================
2611 //function : ExtrusionSweep0D
2613 //=======================================================================
2615 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2616 const SMESH::DirStruct & theStepVector,
2617 CORBA::Long theNbOfSteps)
2618 throw (SALOME::SALOME_Exception)
2620 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2621 if (!myIsPreviewMode) {
2622 TPythonDump() << this << ".ExtrusionSweep0D( "
2623 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2627 //=======================================================================
2628 //function : ExtrusionSweepObject
2630 //=======================================================================
2632 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2633 const SMESH::DirStruct & theStepVector,
2634 CORBA::Long theNbOfSteps)
2635 throw (SALOME::SALOME_Exception)
2637 prepareIdSource( theObject );
2638 SMESH::long_array_var anElementsId = theObject->GetIDs();
2639 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2640 if (!myIsPreviewMode) {
2641 TPythonDump() << this << ".ExtrusionSweepObject( "
2642 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2646 //=======================================================================
2647 //function : ExtrusionSweepObject0D
2649 //=======================================================================
2651 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2652 const SMESH::DirStruct & theStepVector,
2653 CORBA::Long theNbOfSteps)
2654 throw (SALOME::SALOME_Exception)
2656 prepareIdSource( theObject );
2657 SMESH::long_array_var anElementsId = theObject->GetIDs();
2658 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2659 if ( !myIsPreviewMode ) {
2660 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2661 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2665 //=======================================================================
2666 //function : ExtrusionSweepObject1D
2668 //=======================================================================
2670 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2671 const SMESH::DirStruct & theStepVector,
2672 CORBA::Long theNbOfSteps)
2673 throw (SALOME::SALOME_Exception)
2675 prepareIdSource( theObject );
2676 SMESH::long_array_var anElementsId = theObject->GetIDs();
2677 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2678 if ( !myIsPreviewMode ) {
2679 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2680 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2684 //=======================================================================
2685 //function : ExtrusionSweepObject2D
2687 //=======================================================================
2689 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2690 const SMESH::DirStruct & theStepVector,
2691 CORBA::Long theNbOfSteps)
2692 throw (SALOME::SALOME_Exception)
2694 prepareIdSource( theObject );
2695 SMESH::long_array_var anElementsId = theObject->GetIDs();
2696 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2697 if ( !myIsPreviewMode ) {
2698 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2699 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2703 //=======================================================================
2704 //function : ExtrusionSweepMakeGroups
2706 //=======================================================================
2708 SMESH::ListOfGroups*
2709 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2710 const SMESH::DirStruct& theStepVector,
2711 CORBA::Long theNbOfSteps)
2712 throw (SALOME::SALOME_Exception)
2714 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2716 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2718 if (!myIsPreviewMode) {
2719 dumpGroupsList(aPythonDump, aGroups);
2720 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2721 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2726 //=======================================================================
2727 //function : ExtrusionSweepMakeGroups0D
2729 //=======================================================================
2731 SMESH::ListOfGroups*
2732 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2733 const SMESH::DirStruct& theStepVector,
2734 CORBA::Long theNbOfSteps)
2735 throw (SALOME::SALOME_Exception)
2737 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2739 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2741 if (!myIsPreviewMode) {
2742 dumpGroupsList(aPythonDump, aGroups);
2743 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2744 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2749 //=======================================================================
2750 //function : ExtrusionSweepObjectMakeGroups
2752 //=======================================================================
2754 SMESH::ListOfGroups*
2755 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2756 const SMESH::DirStruct& theStepVector,
2757 CORBA::Long theNbOfSteps)
2758 throw (SALOME::SALOME_Exception)
2760 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2762 prepareIdSource( theObject );
2763 SMESH::long_array_var anElementsId = theObject->GetIDs();
2764 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2766 if (!myIsPreviewMode) {
2767 dumpGroupsList(aPythonDump, aGroups);
2768 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2769 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2774 //=======================================================================
2775 //function : ExtrusionSweepObject0DMakeGroups
2777 //=======================================================================
2779 SMESH::ListOfGroups*
2780 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2781 const SMESH::DirStruct& theStepVector,
2782 CORBA::Long theNbOfSteps)
2783 throw (SALOME::SALOME_Exception)
2785 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2787 prepareIdSource( theObject );
2788 SMESH::long_array_var anElementsId = theObject->GetIDs();
2789 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2790 theNbOfSteps, true, SMDSAbs_Node);
2791 if (!myIsPreviewMode) {
2792 dumpGroupsList(aPythonDump, aGroups);
2793 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2794 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2799 //=======================================================================
2800 //function : ExtrusionSweepObject1DMakeGroups
2802 //=======================================================================
2804 SMESH::ListOfGroups*
2805 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2806 const SMESH::DirStruct& theStepVector,
2807 CORBA::Long theNbOfSteps)
2808 throw (SALOME::SALOME_Exception)
2810 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2812 prepareIdSource( theObject );
2813 SMESH::long_array_var anElementsId = theObject->GetIDs();
2814 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2815 theNbOfSteps, true, SMDSAbs_Edge);
2816 if (!myIsPreviewMode) {
2817 dumpGroupsList(aPythonDump, aGroups);
2818 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2819 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2824 //=======================================================================
2825 //function : ExtrusionSweepObject2DMakeGroups
2827 //=======================================================================
2829 SMESH::ListOfGroups*
2830 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2831 const SMESH::DirStruct& theStepVector,
2832 CORBA::Long theNbOfSteps)
2833 throw (SALOME::SALOME_Exception)
2835 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2837 prepareIdSource( theObject );
2838 SMESH::long_array_var anElementsId = theObject->GetIDs();
2839 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2840 theNbOfSteps, true, SMDSAbs_Face);
2841 if (!myIsPreviewMode) {
2842 dumpGroupsList(aPythonDump, aGroups);
2843 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2844 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2850 //=======================================================================
2851 //function : advancedExtrusion
2853 //=======================================================================
2855 SMESH::ListOfGroups*
2856 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2857 const SMESH::DirStruct & theStepVector,
2858 CORBA::Long theNbOfSteps,
2859 CORBA::Long theExtrFlags,
2860 CORBA::Double theSewTolerance,
2861 const bool theMakeGroups)
2862 throw (SALOME::SALOME_Exception)
2867 TIDSortedElemSet elements;
2868 arrayToSet(theIDsOfElements, getMeshDS(), elements);
2870 const SMESH::PointStruct * P = &theStepVector.PS;
2871 gp_Vec stepVec( P->x, P->y, P->z );
2873 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2874 ::SMESH_MeshEditor::PGroupIDs groupIds =
2875 getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2876 theMakeGroups, theExtrFlags, theSewTolerance);
2878 declareMeshModified( /*isReComputeSafe=*/true );
2880 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2882 SMESH_CATCH( SMESH::throwCorbaException );
2886 //=======================================================================
2887 //function : AdvancedExtrusion
2889 //=======================================================================
2891 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2892 const SMESH::DirStruct & theStepVector,
2893 CORBA::Long theNbOfSteps,
2894 CORBA::Long theExtrFlags,
2895 CORBA::Double theSewTolerance)
2896 throw (SALOME::SALOME_Exception)
2898 if ( !myIsPreviewMode ) {
2899 TPythonDump() << "stepVector = " << theStepVector;
2900 TPythonDump() << this << ".AdvancedExtrusion("
2903 << theNbOfSteps << ","
2904 << theExtrFlags << ", "
2905 << theSewTolerance << " )";
2907 advancedExtrusion( theIDsOfElements,
2915 //=======================================================================
2916 //function : AdvancedExtrusionMakeGroups
2918 //=======================================================================
2919 SMESH::ListOfGroups*
2920 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2921 const SMESH::DirStruct& theStepVector,
2922 CORBA::Long theNbOfSteps,
2923 CORBA::Long theExtrFlags,
2924 CORBA::Double theSewTolerance)
2925 throw (SALOME::SALOME_Exception)
2927 if (!myIsPreviewMode) {
2928 TPythonDump() << "stepVector = " << theStepVector;
2930 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2932 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2939 if (!myIsPreviewMode) {
2940 dumpGroupsList(aPythonDump, aGroups);
2941 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2944 << theNbOfSteps << ","
2945 << theExtrFlags << ", "
2946 << theSewTolerance << " )";
2952 //================================================================================
2954 * \brief Convert extrusion error to IDL enum
2956 //================================================================================
2958 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2960 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2964 RETCASE( EXTR_NO_ELEMENTS );
2965 RETCASE( EXTR_PATH_NOT_EDGE );
2966 RETCASE( EXTR_BAD_PATH_SHAPE );
2967 RETCASE( EXTR_BAD_STARTING_NODE );
2968 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2969 RETCASE( EXTR_CANT_GET_TANGENT );
2971 return SMESH::SMESH_MeshEditor::EXTR_OK;
2975 //=======================================================================
2976 //function : extrusionAlongPath
2978 //=======================================================================
2979 SMESH::ListOfGroups*
2980 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2981 SMESH::SMESH_Mesh_ptr thePathMesh,
2982 GEOM::GEOM_Object_ptr thePathShape,
2983 CORBA::Long theNodeStart,
2984 CORBA::Boolean theHasAngles,
2985 const SMESH::double_array & theAngles,
2986 CORBA::Boolean theHasRefPoint,
2987 const SMESH::PointStruct & theRefPoint,
2988 const bool theMakeGroups,
2989 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2990 const SMDSAbs_ElementType theElementType)
2991 throw (SALOME::SALOME_Exception)
2994 MESSAGE("extrusionAlongPath");
2997 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2998 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3001 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3003 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3004 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3006 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
3007 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3011 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
3013 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3017 TIDSortedElemSet elements;
3018 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
3020 list<double> angles;
3021 for (int i = 0; i < theAngles.length(); i++) {
3022 angles.push_back( theAngles[i] );
3025 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
3027 int nbOldGroups = myMesh->NbGroup();
3029 ::SMESH_MeshEditor::Extrusion_Error error =
3030 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
3031 theHasAngles, angles, false,
3032 theHasRefPoint, refPnt, theMakeGroups );
3034 declareMeshModified( /*isReComputeSafe=*/true );
3035 theError = convExtrError( error );
3037 if ( theMakeGroups ) {
3038 list<int> groupIDs = myMesh->GetGroupIds();
3039 list<int>::iterator newBegin = groupIDs.begin();
3040 std::advance( newBegin, nbOldGroups ); // skip old groups
3041 groupIDs.erase( groupIDs.begin(), newBegin );
3042 return getGroups( & groupIDs );
3046 SMESH_CATCH( SMESH::throwCorbaException );
3050 //=======================================================================
3051 //function : extrusionAlongPathX
3053 //=======================================================================
3055 SMESH::ListOfGroups*
3056 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
3057 SMESH::SMESH_IDSource_ptr Path,
3058 CORBA::Long NodeStart,
3059 CORBA::Boolean HasAngles,
3060 const SMESH::double_array& Angles,
3061 CORBA::Boolean LinearVariation,
3062 CORBA::Boolean HasRefPoint,
3063 const SMESH::PointStruct& RefPoint,
3065 const SMDSAbs_ElementType ElementType,
3066 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
3067 throw (SALOME::SALOME_Exception)
3070 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
3074 list<double> angles;
3075 for (int i = 0; i < Angles.length(); i++) {
3076 angles.push_back( Angles[i] );
3078 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
3079 int nbOldGroups = myMesh->NbGroup();
3081 if ( Path->_is_nil() ) {
3082 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3086 TIDSortedElemSet elements, copyElements;
3087 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
3089 TIDSortedElemSet* workElements = &elements;
3091 if ( myIsPreviewMode )
3093 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
3094 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
3095 workElements = & copyElements;
3099 ::SMESH_MeshEditor::Extrusion_Error error;
3101 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
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 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
3111 HasAngles, angles, LinearVariation,
3112 HasRefPoint, refPnt, MakeGroups );
3113 declareMeshModified( /*isReComputeSafe=*/true );
3115 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
3118 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
3119 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
3120 SMDS_MeshNode* aNodeStart =
3121 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3122 if ( !aNodeStart ) {
3123 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3126 SMESH_subMesh* aSubMesh =
3127 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
3128 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
3129 HasAngles, angles, LinearVariation,
3130 HasRefPoint, refPnt, MakeGroups );
3131 declareMeshModified( /*isReComputeSafe=*/true );
3133 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
3135 // path as group of 1D elements
3141 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3145 Error = convExtrError( error );
3148 list<int> groupIDs = myMesh->GetGroupIds();
3149 list<int>::iterator newBegin = groupIDs.begin();
3150 std::advance( newBegin, nbOldGroups ); // skip old groups
3151 groupIDs.erase( groupIDs.begin(), newBegin );
3152 return getGroups( & groupIDs );
3156 SMESH_CATCH( SMESH::throwCorbaException );
3160 //=======================================================================
3161 //function : ExtrusionAlongPath
3163 //=======================================================================
3165 SMESH::SMESH_MeshEditor::Extrusion_Error
3166 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3167 SMESH::SMESH_Mesh_ptr thePathMesh,
3168 GEOM::GEOM_Object_ptr thePathShape,
3169 CORBA::Long theNodeStart,
3170 CORBA::Boolean theHasAngles,
3171 const SMESH::double_array & theAngles,
3172 CORBA::Boolean theHasRefPoint,
3173 const SMESH::PointStruct & theRefPoint)
3174 throw (SALOME::SALOME_Exception)
3176 MESSAGE("ExtrusionAlongPath");
3177 if ( !myIsPreviewMode ) {
3178 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
3179 << theIDsOfElements << ", "
3180 << thePathMesh << ", "
3181 << thePathShape << ", "
3182 << theNodeStart << ", "
3183 << theHasAngles << ", "
3184 << theAngles << ", "
3185 << theHasRefPoint << ", "
3186 << "SMESH.PointStruct( "
3187 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3188 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3189 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3191 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3192 extrusionAlongPath( theIDsOfElements,
3205 //=======================================================================
3206 //function : ExtrusionAlongPathObject
3208 //=======================================================================
3210 SMESH::SMESH_MeshEditor::Extrusion_Error
3211 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
3212 SMESH::SMESH_Mesh_ptr thePathMesh,
3213 GEOM::GEOM_Object_ptr thePathShape,
3214 CORBA::Long theNodeStart,
3215 CORBA::Boolean theHasAngles,
3216 const SMESH::double_array & theAngles,
3217 CORBA::Boolean theHasRefPoint,
3218 const SMESH::PointStruct & theRefPoint)
3219 throw (SALOME::SALOME_Exception)
3221 if ( !myIsPreviewMode ) {
3222 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
3223 << theObject << ", "
3224 << thePathMesh << ", "
3225 << thePathShape << ", "
3226 << theNodeStart << ", "
3227 << theHasAngles << ", "
3228 << theAngles << ", "
3229 << theHasRefPoint << ", "
3230 << "SMESH.PointStruct( "
3231 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3232 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3233 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3235 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3236 prepareIdSource( theObject );
3237 SMESH::long_array_var anElementsId = theObject->GetIDs();
3238 extrusionAlongPath( anElementsId,
3251 //=======================================================================
3252 //function : ExtrusionAlongPathObject1D
3254 //=======================================================================
3256 SMESH::SMESH_MeshEditor::Extrusion_Error
3257 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
3258 SMESH::SMESH_Mesh_ptr thePathMesh,
3259 GEOM::GEOM_Object_ptr thePathShape,
3260 CORBA::Long theNodeStart,
3261 CORBA::Boolean theHasAngles,
3262 const SMESH::double_array & theAngles,
3263 CORBA::Boolean theHasRefPoint,
3264 const SMESH::PointStruct & theRefPoint)
3265 throw (SALOME::SALOME_Exception)
3267 if ( !myIsPreviewMode ) {
3268 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
3269 << theObject << ", "
3270 << thePathMesh << ", "
3271 << thePathShape << ", "
3272 << theNodeStart << ", "
3273 << theHasAngles << ", "
3274 << theAngles << ", "
3275 << theHasRefPoint << ", "
3276 << "SMESH.PointStruct( "
3277 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3278 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3279 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3281 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3282 prepareIdSource( theObject );
3283 SMESH::long_array_var anElementsId = theObject->GetIDs();
3284 extrusionAlongPath( anElementsId,
3298 //=======================================================================
3299 //function : ExtrusionAlongPathObject2D
3301 //=======================================================================
3303 SMESH::SMESH_MeshEditor::Extrusion_Error
3304 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3305 SMESH::SMESH_Mesh_ptr thePathMesh,
3306 GEOM::GEOM_Object_ptr thePathShape,
3307 CORBA::Long theNodeStart,
3308 CORBA::Boolean theHasAngles,
3309 const SMESH::double_array & theAngles,
3310 CORBA::Boolean theHasRefPoint,
3311 const SMESH::PointStruct & theRefPoint)
3312 throw (SALOME::SALOME_Exception)
3314 if ( !myIsPreviewMode ) {
3315 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3316 << theObject << ", "
3317 << thePathMesh << ", "
3318 << thePathShape << ", "
3319 << theNodeStart << ", "
3320 << theHasAngles << ", "
3321 << theAngles << ", "
3322 << theHasRefPoint << ", "
3323 << "SMESH.PointStruct( "
3324 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3325 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3326 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3328 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3329 prepareIdSource( theObject );
3330 SMESH::long_array_var anElementsId = theObject->GetIDs();
3331 extrusionAlongPath( anElementsId,
3346 //=======================================================================
3347 //function : ExtrusionAlongPathMakeGroups
3349 //=======================================================================
3351 SMESH::ListOfGroups*
3352 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3353 SMESH::SMESH_Mesh_ptr thePathMesh,
3354 GEOM::GEOM_Object_ptr thePathShape,
3355 CORBA::Long theNodeStart,
3356 CORBA::Boolean theHasAngles,
3357 const SMESH::double_array& theAngles,
3358 CORBA::Boolean theHasRefPoint,
3359 const SMESH::PointStruct& theRefPoint,
3360 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3361 throw (SALOME::SALOME_Exception)
3363 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3365 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3375 if (!myIsPreviewMode) {
3376 bool isDumpGroups = aGroups && aGroups->length() > 0;
3378 aPythonDump << "(" << aGroups << ", error)";
3380 aPythonDump <<"error";
3382 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3383 << theIDsOfElements << ", "
3384 << thePathMesh << ", "
3385 << thePathShape << ", "
3386 << theNodeStart << ", "
3387 << theHasAngles << ", "
3388 << theAngles << ", "
3389 << theHasRefPoint << ", "
3390 << "SMESH.PointStruct( "
3391 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3392 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3393 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3398 //=======================================================================
3399 //function : ExtrusionAlongPathObjectMakeGroups
3401 //=======================================================================
3403 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3404 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3405 SMESH::SMESH_Mesh_ptr thePathMesh,
3406 GEOM::GEOM_Object_ptr thePathShape,
3407 CORBA::Long theNodeStart,
3408 CORBA::Boolean theHasAngles,
3409 const SMESH::double_array& theAngles,
3410 CORBA::Boolean theHasRefPoint,
3411 const SMESH::PointStruct& theRefPoint,
3412 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3413 throw (SALOME::SALOME_Exception)
3415 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3417 prepareIdSource( theObject );
3418 SMESH::long_array_var anElementsId = theObject->GetIDs();
3419 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3430 if (!myIsPreviewMode) {
3431 bool isDumpGroups = aGroups && aGroups->length() > 0;
3433 aPythonDump << "(" << aGroups << ", error)";
3435 aPythonDump <<"error";
3437 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3438 << theObject << ", "
3439 << thePathMesh << ", "
3440 << thePathShape << ", "
3441 << theNodeStart << ", "
3442 << theHasAngles << ", "
3443 << theAngles << ", "
3444 << theHasRefPoint << ", "
3445 << "SMESH.PointStruct( "
3446 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3447 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3448 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3453 //=======================================================================
3454 //function : ExtrusionAlongPathObject1DMakeGroups
3456 //=======================================================================
3458 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3459 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3460 SMESH::SMESH_Mesh_ptr thePathMesh,
3461 GEOM::GEOM_Object_ptr thePathShape,
3462 CORBA::Long theNodeStart,
3463 CORBA::Boolean theHasAngles,
3464 const SMESH::double_array& theAngles,
3465 CORBA::Boolean theHasRefPoint,
3466 const SMESH::PointStruct& theRefPoint,
3467 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3468 throw (SALOME::SALOME_Exception)
3470 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3472 prepareIdSource( theObject );
3473 SMESH::long_array_var anElementsId = theObject->GetIDs();
3474 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3486 if (!myIsPreviewMode) {
3487 bool isDumpGroups = aGroups && aGroups->length() > 0;
3489 aPythonDump << "(" << aGroups << ", error)";
3491 aPythonDump << "error";
3493 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3494 << theObject << ", "
3495 << thePathMesh << ", "
3496 << thePathShape << ", "
3497 << theNodeStart << ", "
3498 << theHasAngles << ", "
3499 << theAngles << ", "
3500 << theHasRefPoint << ", "
3501 << "SMESH.PointStruct( "
3502 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3503 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3504 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3509 //=======================================================================
3510 //function : ExtrusionAlongPathObject2DMakeGroups
3512 //=======================================================================
3514 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3515 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3516 SMESH::SMESH_Mesh_ptr thePathMesh,
3517 GEOM::GEOM_Object_ptr thePathShape,
3518 CORBA::Long theNodeStart,
3519 CORBA::Boolean theHasAngles,
3520 const SMESH::double_array& theAngles,
3521 CORBA::Boolean theHasRefPoint,
3522 const SMESH::PointStruct& theRefPoint,
3523 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3524 throw (SALOME::SALOME_Exception)
3526 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3528 prepareIdSource( theObject );
3529 SMESH::long_array_var anElementsId = theObject->GetIDs();
3530 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3542 if (!myIsPreviewMode) {
3543 bool isDumpGroups = aGroups && aGroups->length() > 0;
3545 aPythonDump << "(" << aGroups << ", error)";
3547 aPythonDump << "error";
3549 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3550 << theObject << ", "
3551 << thePathMesh << ", "
3552 << thePathShape << ", "
3553 << theNodeStart << ", "
3554 << theHasAngles << ", "
3555 << theAngles << ", "
3556 << theHasRefPoint << ", "
3557 << "SMESH.PointStruct( "
3558 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3559 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3560 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3565 //=======================================================================
3566 //function : ExtrusionAlongPathObjX
3568 //=======================================================================
3570 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3571 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3572 SMESH::SMESH_IDSource_ptr Path,
3573 CORBA::Long NodeStart,
3574 CORBA::Boolean HasAngles,
3575 const SMESH::double_array& Angles,
3576 CORBA::Boolean LinearVariation,
3577 CORBA::Boolean HasRefPoint,
3578 const SMESH::PointStruct& RefPoint,
3579 CORBA::Boolean MakeGroups,
3580 SMESH::ElementType ElemType,
3581 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3582 throw (SALOME::SALOME_Exception)
3584 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3586 prepareIdSource( Object );
3587 SMESH::long_array_var anElementsId = Object->GetIDs();
3588 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3597 (SMDSAbs_ElementType)ElemType,
3600 if (!myIsPreviewMode) {
3601 bool isDumpGroups = aGroups && aGroups->length() > 0;
3603 aPythonDump << "(" << *aGroups << ", error)";
3605 aPythonDump << "error";
3607 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3610 << NodeStart << ", "
3611 << HasAngles << ", "
3612 << TVar( Angles ) << ", "
3613 << LinearVariation << ", "
3614 << HasRefPoint << ", "
3615 << "SMESH.PointStruct( "
3616 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3617 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3618 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3619 << MakeGroups << ", "
3620 << ElemType << " )";
3625 //=======================================================================
3626 //function : ExtrusionAlongPathX
3628 //=======================================================================
3630 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3631 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3632 SMESH::SMESH_IDSource_ptr Path,
3633 CORBA::Long NodeStart,
3634 CORBA::Boolean HasAngles,
3635 const SMESH::double_array& Angles,
3636 CORBA::Boolean LinearVariation,
3637 CORBA::Boolean HasRefPoint,
3638 const SMESH::PointStruct& RefPoint,
3639 CORBA::Boolean MakeGroups,
3640 SMESH::ElementType ElemType,
3641 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3642 throw (SALOME::SALOME_Exception)
3644 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3646 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3655 (SMDSAbs_ElementType)ElemType,
3658 if (!myIsPreviewMode) {
3659 bool isDumpGroups = aGroups && aGroups->length() > 0;
3661 aPythonDump << "(" << *aGroups << ", error)";
3663 aPythonDump <<"error";
3665 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3666 << IDsOfElements << ", "
3668 << NodeStart << ", "
3669 << HasAngles << ", "
3670 << TVar( Angles ) << ", "
3671 << LinearVariation << ", "
3672 << HasRefPoint << ", "
3673 << "SMESH.PointStruct( "
3674 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3675 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3676 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3677 << MakeGroups << ", "
3678 << ElemType << " )";
3683 //================================================================================
3685 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3686 * of given angles along path steps
3687 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3688 * which proceeds the extrusion
3689 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3690 * is used to define the sub-mesh for the path
3692 //================================================================================
3694 SMESH::double_array*
3695 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3696 GEOM::GEOM_Object_ptr thePathShape,
3697 const SMESH::double_array & theAngles)
3699 SMESH::double_array_var aResult = new SMESH::double_array();
3700 int nbAngles = theAngles.length();
3701 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3703 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3704 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3705 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3706 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3707 return aResult._retn();
3708 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3709 if ( nbSteps == nbAngles )
3711 aResult.inout() = theAngles;
3715 aResult->length( nbSteps );
3716 double rAn2St = double( nbAngles ) / double( nbSteps );
3717 double angPrev = 0, angle;
3718 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3720 double angCur = rAn2St * ( iSt+1 );
3721 double angCurFloor = floor( angCur );
3722 double angPrevFloor = floor( angPrev );
3723 if ( angPrevFloor == angCurFloor )
3724 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3727 int iP = int( angPrevFloor );
3728 double angPrevCeil = ceil(angPrev);
3729 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3731 int iC = int( angCurFloor );
3732 if ( iC < nbAngles )
3733 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3735 iP = int( angPrevCeil );
3737 angle += theAngles[ iC ];
3739 aResult[ iSt ] = angle;
3744 // Update Python script
3745 TPythonDump() << "rotAngles = " << theAngles;
3746 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3747 << thePathMesh << ", "
3748 << thePathShape << ", "
3751 return aResult._retn();
3754 //=======================================================================
3757 //=======================================================================
3759 SMESH::ListOfGroups*
3760 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3761 const SMESH::AxisStruct & theAxis,
3762 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3763 CORBA::Boolean theCopy,
3765 ::SMESH_Mesh* theTargetMesh)
3766 throw (SALOME::SALOME_Exception)
3771 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3772 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3774 if ( theTargetMesh )
3778 switch ( theMirrorType ) {
3779 case SMESH::SMESH_MeshEditor::POINT:
3780 aTrsf.SetMirror( P );
3782 case SMESH::SMESH_MeshEditor::AXIS:
3783 aTrsf.SetMirror( gp_Ax1( P, V ));
3786 aTrsf.SetMirror( gp_Ax2( P, V ));
3789 TIDSortedElemSet copyElements;
3790 TIDSortedElemSet* workElements = & theElements;
3792 if ( myIsPreviewMode )
3794 TPreviewMesh * tmpMesh = getPreviewMesh();
3795 tmpMesh->Copy( theElements, copyElements);
3796 if ( !theCopy && !theTargetMesh )
3798 TIDSortedElemSet elemsAround, elemsAroundCopy;
3799 getElementsAround( theElements, getMeshDS(), elemsAround );
3800 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3802 workElements = & copyElements;
3803 theMakeGroups = false;
3806 ::SMESH_MeshEditor::PGroupIDs groupIds =
3807 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3809 if ( theCopy && !myIsPreviewMode)
3811 if ( theTargetMesh )
3813 theTargetMesh->GetMeshDS()->Modified();
3817 declareMeshModified( /*isReComputeSafe=*/false );
3820 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3822 SMESH_CATCH( SMESH::throwCorbaException );
3826 //=======================================================================
3829 //=======================================================================
3831 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3832 const SMESH::AxisStruct & theAxis,
3833 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3834 CORBA::Boolean theCopy)
3835 throw (SALOME::SALOME_Exception)
3837 if ( !myIsPreviewMode ) {
3838 TPythonDump() << this << ".Mirror( "
3839 << theIDsOfElements << ", "
3841 << mirrorTypeName(theMirrorType) << ", "
3844 if ( theIDsOfElements.length() > 0 )
3846 TIDSortedElemSet elements;
3847 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3848 mirror(elements, theAxis, theMirrorType, theCopy, false);
3853 //=======================================================================
3854 //function : MirrorObject
3856 //=======================================================================
3858 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3859 const SMESH::AxisStruct & theAxis,
3860 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3861 CORBA::Boolean theCopy)
3862 throw (SALOME::SALOME_Exception)
3864 if ( !myIsPreviewMode ) {
3865 TPythonDump() << this << ".MirrorObject( "
3866 << theObject << ", "
3868 << mirrorTypeName(theMirrorType) << ", "
3871 TIDSortedElemSet elements;
3873 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3875 prepareIdSource( theObject );
3876 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3877 mirror(elements, theAxis, theMirrorType, theCopy, false);
3880 //=======================================================================
3881 //function : MirrorMakeGroups
3883 //=======================================================================
3885 SMESH::ListOfGroups*
3886 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3887 const SMESH::AxisStruct& theMirror,
3888 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3889 throw (SALOME::SALOME_Exception)
3891 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3893 SMESH::ListOfGroups * aGroups = 0;
3894 if ( theIDsOfElements.length() > 0 )
3896 TIDSortedElemSet elements;
3897 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3898 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3900 if (!myIsPreviewMode) {
3901 dumpGroupsList(aPythonDump, aGroups);
3902 aPythonDump << this << ".MirrorMakeGroups( "
3903 << theIDsOfElements << ", "
3904 << theMirror << ", "
3905 << mirrorTypeName(theMirrorType) << " )";
3910 //=======================================================================
3911 //function : MirrorObjectMakeGroups
3913 //=======================================================================
3915 SMESH::ListOfGroups*
3916 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3917 const SMESH::AxisStruct& theMirror,
3918 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3919 throw (SALOME::SALOME_Exception)
3921 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3923 SMESH::ListOfGroups * aGroups = 0;
3924 TIDSortedElemSet elements;
3925 prepareIdSource( theObject );
3926 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3927 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3929 if (!myIsPreviewMode)
3931 dumpGroupsList(aPythonDump,aGroups);
3932 aPythonDump << this << ".MirrorObjectMakeGroups( "
3933 << theObject << ", "
3934 << theMirror << ", "
3935 << mirrorTypeName(theMirrorType) << " )";
3940 //=======================================================================
3941 //function : MirrorMakeMesh
3943 //=======================================================================
3945 SMESH::SMESH_Mesh_ptr
3946 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3947 const SMESH::AxisStruct& theMirror,
3948 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3949 CORBA::Boolean theCopyGroups,
3950 const char* theMeshName)
3951 throw (SALOME::SALOME_Exception)
3953 SMESH_Mesh_i* mesh_i;
3954 SMESH::SMESH_Mesh_var mesh;
3955 { // open new scope to dump "MakeMesh" command
3956 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3958 TPythonDump pydump; // to prevent dump at mesh creation
3960 mesh = makeMesh( theMeshName );
3961 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3962 if (mesh_i && theIDsOfElements.length() > 0 )
3964 TIDSortedElemSet elements;
3965 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3966 mirror(elements, theMirror, theMirrorType,
3967 false, theCopyGroups, & mesh_i->GetImpl());
3968 mesh_i->CreateGroupServants();
3971 if (!myIsPreviewMode) {
3972 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3973 << theIDsOfElements << ", "
3974 << theMirror << ", "
3975 << mirrorTypeName(theMirrorType) << ", "
3976 << theCopyGroups << ", '"
3977 << theMeshName << "' )";
3982 if (!myIsPreviewMode && mesh_i)
3983 mesh_i->GetGroups();
3985 return mesh._retn();
3988 //=======================================================================
3989 //function : MirrorObjectMakeMesh
3991 //=======================================================================
3993 SMESH::SMESH_Mesh_ptr
3994 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3995 const SMESH::AxisStruct& theMirror,
3996 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3997 CORBA::Boolean theCopyGroups,
3998 const char* theMeshName)
3999 throw (SALOME::SALOME_Exception)
4001 SMESH_Mesh_i* mesh_i;
4002 SMESH::SMESH_Mesh_var mesh;
4003 { // open new scope to dump "MakeMesh" command
4004 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4006 TPythonDump pydump; // to prevent dump at mesh creation
4008 mesh = makeMesh( theMeshName );
4009 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4010 TIDSortedElemSet elements;
4011 prepareIdSource( theObject );
4013 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4015 mirror(elements, theMirror, theMirrorType,
4016 false, theCopyGroups, & mesh_i->GetImpl());
4017 mesh_i->CreateGroupServants();
4019 if (!myIsPreviewMode) {
4020 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
4021 << theObject << ", "
4022 << theMirror << ", "
4023 << mirrorTypeName(theMirrorType) << ", "
4024 << theCopyGroups << ", '"
4025 << theMeshName << "' )";
4030 if (!myIsPreviewMode && mesh_i)
4031 mesh_i->GetGroups();
4033 return mesh._retn();
4036 //=======================================================================
4037 //function : translate
4039 //=======================================================================
4041 SMESH::ListOfGroups*
4042 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
4043 const SMESH::DirStruct & theVector,
4044 CORBA::Boolean theCopy,
4046 ::SMESH_Mesh* theTargetMesh)
4047 throw (SALOME::SALOME_Exception)
4052 if ( theTargetMesh )
4056 const SMESH::PointStruct * P = &theVector.PS;
4057 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
4059 TIDSortedElemSet copyElements;
4060 TIDSortedElemSet* workElements = &theElements;
4062 if ( myIsPreviewMode )
4064 TPreviewMesh * tmpMesh = getPreviewMesh();
4065 tmpMesh->Copy( theElements, copyElements);
4066 if ( !theCopy && !theTargetMesh )
4068 TIDSortedElemSet elemsAround, elemsAroundCopy;
4069 getElementsAround( theElements, getMeshDS(), elemsAround );
4070 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4072 workElements = & copyElements;
4073 theMakeGroups = false;
4076 ::SMESH_MeshEditor::PGroupIDs groupIds =
4077 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4079 if ( theCopy && !myIsPreviewMode )
4081 if ( theTargetMesh )
4083 theTargetMesh->GetMeshDS()->Modified();
4087 declareMeshModified( /*isReComputeSafe=*/false );
4091 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4093 SMESH_CATCH( SMESH::throwCorbaException );
4097 //=======================================================================
4098 //function : Translate
4100 //=======================================================================
4102 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
4103 const SMESH::DirStruct & theVector,
4104 CORBA::Boolean theCopy)
4105 throw (SALOME::SALOME_Exception)
4107 if (!myIsPreviewMode) {
4108 TPythonDump() << this << ".Translate( "
4109 << theIDsOfElements << ", "
4110 << theVector << ", "
4113 if (theIDsOfElements.length()) {
4114 TIDSortedElemSet elements;
4115 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4116 translate(elements, theVector, theCopy, false);
4120 //=======================================================================
4121 //function : TranslateObject
4123 //=======================================================================
4125 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
4126 const SMESH::DirStruct & theVector,
4127 CORBA::Boolean theCopy)
4128 throw (SALOME::SALOME_Exception)
4130 if (!myIsPreviewMode) {
4131 TPythonDump() << this << ".TranslateObject( "
4132 << theObject << ", "
4133 << theVector << ", "
4136 TIDSortedElemSet elements;
4138 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4140 prepareIdSource( theObject );
4141 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4142 translate(elements, theVector, theCopy, false);
4145 //=======================================================================
4146 //function : TranslateMakeGroups
4148 //=======================================================================
4150 SMESH::ListOfGroups*
4151 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
4152 const SMESH::DirStruct& theVector)
4153 throw (SALOME::SALOME_Exception)
4155 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4157 SMESH::ListOfGroups * aGroups = 0;
4158 if (theIDsOfElements.length()) {
4159 TIDSortedElemSet elements;
4160 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4161 aGroups = translate(elements,theVector,true,true);
4163 if (!myIsPreviewMode) {
4164 dumpGroupsList(aPythonDump, aGroups);
4165 aPythonDump << this << ".TranslateMakeGroups( "
4166 << theIDsOfElements << ", "
4167 << theVector << " )";
4172 //=======================================================================
4173 //function : TranslateObjectMakeGroups
4175 //=======================================================================
4177 SMESH::ListOfGroups*
4178 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4179 const SMESH::DirStruct& theVector)
4180 throw (SALOME::SALOME_Exception)
4182 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4184 SMESH::ListOfGroups * aGroups = 0;
4185 TIDSortedElemSet elements;
4186 prepareIdSource( theObject );
4187 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4188 aGroups = translate(elements, theVector, true, true);
4190 if (!myIsPreviewMode) {
4191 dumpGroupsList(aPythonDump, aGroups);
4192 aPythonDump << this << ".TranslateObjectMakeGroups( "
4193 << theObject << ", "
4194 << theVector << " )";
4199 //=======================================================================
4200 //function : TranslateMakeMesh
4202 //=======================================================================
4204 SMESH::SMESH_Mesh_ptr
4205 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
4206 const SMESH::DirStruct& theVector,
4207 CORBA::Boolean theCopyGroups,
4208 const char* theMeshName)
4209 throw (SALOME::SALOME_Exception)
4211 SMESH_Mesh_i* mesh_i;
4212 SMESH::SMESH_Mesh_var mesh;
4214 { // open new scope to dump "MakeMesh" command
4215 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4217 TPythonDump pydump; // to prevent dump at mesh creation
4219 mesh = makeMesh( theMeshName );
4220 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4222 if ( mesh_i && theIDsOfElements.length() )
4224 TIDSortedElemSet elements;
4225 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4226 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
4227 mesh_i->CreateGroupServants();
4230 if ( !myIsPreviewMode ) {
4231 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
4232 << theIDsOfElements << ", "
4233 << theVector << ", "
4234 << theCopyGroups << ", '"
4235 << theMeshName << "' )";
4240 if (!myIsPreviewMode && mesh_i)
4241 mesh_i->GetGroups();
4243 return mesh._retn();
4246 //=======================================================================
4247 //function : TranslateObjectMakeMesh
4249 //=======================================================================
4251 SMESH::SMESH_Mesh_ptr
4252 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4253 const SMESH::DirStruct& theVector,
4254 CORBA::Boolean theCopyGroups,
4255 const char* theMeshName)
4256 throw (SALOME::SALOME_Exception)
4259 SMESH_Mesh_i* mesh_i;
4260 SMESH::SMESH_Mesh_var mesh;
4261 { // open new scope to dump "MakeMesh" command
4262 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4264 TPythonDump pydump; // to prevent dump at mesh creation
4265 mesh = makeMesh( theMeshName );
4266 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4268 TIDSortedElemSet elements;
4269 prepareIdSource( theObject );
4271 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4273 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
4274 mesh_i->CreateGroupServants();
4276 if ( !myIsPreviewMode ) {
4277 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
4278 << theObject << ", "
4279 << theVector << ", "
4280 << theCopyGroups << ", '"
4281 << theMeshName << "' )";
4286 if (!myIsPreviewMode && mesh_i)
4287 mesh_i->GetGroups();
4289 return mesh._retn();
4291 SMESH_CATCH( SMESH::throwCorbaException );
4295 //=======================================================================
4298 //=======================================================================
4300 SMESH::ListOfGroups*
4301 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
4302 const SMESH::AxisStruct & theAxis,
4303 CORBA::Double theAngle,
4304 CORBA::Boolean theCopy,
4306 ::SMESH_Mesh* theTargetMesh)
4307 throw (SALOME::SALOME_Exception)
4312 if ( theTargetMesh )
4315 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
4316 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
4319 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
4321 TIDSortedElemSet copyElements;
4322 TIDSortedElemSet* workElements = &theElements;
4323 if ( myIsPreviewMode ) {
4324 TPreviewMesh * tmpMesh = getPreviewMesh();
4325 tmpMesh->Copy( theElements, copyElements );
4326 if ( !theCopy && !theTargetMesh )
4328 TIDSortedElemSet elemsAround, elemsAroundCopy;
4329 getElementsAround( theElements, getMeshDS(), elemsAround );
4330 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4332 workElements = ©Elements;
4333 theMakeGroups = false;
4336 ::SMESH_MeshEditor::PGroupIDs groupIds =
4337 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4339 if ( theCopy && !myIsPreviewMode)
4341 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4342 else declareMeshModified( /*isReComputeSafe=*/false );
4345 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4347 SMESH_CATCH( SMESH::throwCorbaException );
4351 //=======================================================================
4354 //=======================================================================
4356 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4357 const SMESH::AxisStruct & theAxis,
4358 CORBA::Double theAngle,
4359 CORBA::Boolean theCopy)
4360 throw (SALOME::SALOME_Exception)
4362 if (!myIsPreviewMode) {
4363 TPythonDump() << this << ".Rotate( "
4364 << theIDsOfElements << ", "
4366 << TVar( theAngle ) << ", "
4369 if (theIDsOfElements.length() > 0)
4371 TIDSortedElemSet elements;
4372 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4373 rotate(elements,theAxis,theAngle,theCopy,false);
4377 //=======================================================================
4378 //function : RotateObject
4380 //=======================================================================
4382 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4383 const SMESH::AxisStruct & theAxis,
4384 CORBA::Double theAngle,
4385 CORBA::Boolean theCopy)
4386 throw (SALOME::SALOME_Exception)
4388 if ( !myIsPreviewMode ) {
4389 TPythonDump() << this << ".RotateObject( "
4390 << theObject << ", "
4392 << TVar( theAngle ) << ", "
4395 TIDSortedElemSet elements;
4396 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4397 prepareIdSource( theObject );
4398 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4399 rotate(elements,theAxis,theAngle,theCopy,false);
4402 //=======================================================================
4403 //function : RotateMakeGroups
4405 //=======================================================================
4407 SMESH::ListOfGroups*
4408 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4409 const SMESH::AxisStruct& theAxis,
4410 CORBA::Double theAngle)
4411 throw (SALOME::SALOME_Exception)
4413 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4415 SMESH::ListOfGroups * aGroups = 0;
4416 if (theIDsOfElements.length() > 0)
4418 TIDSortedElemSet elements;
4419 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4420 aGroups = rotate(elements,theAxis,theAngle,true,true);
4422 if (!myIsPreviewMode) {
4423 dumpGroupsList(aPythonDump, aGroups);
4424 aPythonDump << this << ".RotateMakeGroups( "
4425 << theIDsOfElements << ", "
4427 << TVar( theAngle ) << " )";
4432 //=======================================================================
4433 //function : RotateObjectMakeGroups
4435 //=======================================================================
4437 SMESH::ListOfGroups*
4438 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4439 const SMESH::AxisStruct& theAxis,
4440 CORBA::Double theAngle)
4441 throw (SALOME::SALOME_Exception)
4443 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4445 SMESH::ListOfGroups * aGroups = 0;
4446 TIDSortedElemSet elements;
4447 prepareIdSource( theObject );
4448 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4449 aGroups = rotate(elements, theAxis, theAngle, true, true);
4451 if (!myIsPreviewMode) {
4452 dumpGroupsList(aPythonDump, aGroups);
4453 aPythonDump << this << ".RotateObjectMakeGroups( "
4454 << theObject << ", "
4456 << TVar( theAngle ) << " )";
4461 //=======================================================================
4462 //function : RotateMakeMesh
4464 //=======================================================================
4466 SMESH::SMESH_Mesh_ptr
4467 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4468 const SMESH::AxisStruct& theAxis,
4469 CORBA::Double theAngleInRadians,
4470 CORBA::Boolean theCopyGroups,
4471 const char* theMeshName)
4472 throw (SALOME::SALOME_Exception)
4475 SMESH::SMESH_Mesh_var mesh;
4476 SMESH_Mesh_i* mesh_i;
4478 { // open new scope to dump "MakeMesh" command
4479 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4481 TPythonDump pydump; // to prevent dump at mesh creation
4483 mesh = makeMesh( theMeshName );
4484 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4486 if ( mesh_i && theIDsOfElements.length() > 0 )
4488 TIDSortedElemSet elements;
4489 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4490 rotate(elements, theAxis, theAngleInRadians,
4491 false, theCopyGroups, & mesh_i->GetImpl());
4492 mesh_i->CreateGroupServants();
4494 if ( !myIsPreviewMode ) {
4495 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4496 << theIDsOfElements << ", "
4498 << TVar( theAngleInRadians ) << ", "
4499 << theCopyGroups << ", '"
4500 << theMeshName << "' )";
4505 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4506 mesh_i->GetGroups();
4508 return mesh._retn();
4510 SMESH_CATCH( SMESH::throwCorbaException );
4514 //=======================================================================
4515 //function : RotateObjectMakeMesh
4517 //=======================================================================
4519 SMESH::SMESH_Mesh_ptr
4520 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4521 const SMESH::AxisStruct& theAxis,
4522 CORBA::Double theAngleInRadians,
4523 CORBA::Boolean theCopyGroups,
4524 const char* theMeshName)
4525 throw (SALOME::SALOME_Exception)
4528 SMESH::SMESH_Mesh_var mesh;
4529 SMESH_Mesh_i* mesh_i;
4531 {// open new scope to dump "MakeMesh" command
4532 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4534 TPythonDump pydump; // to prevent dump at mesh creation
4535 mesh = makeMesh( theMeshName );
4536 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4538 TIDSortedElemSet elements;
4539 prepareIdSource( theObject );
4541 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4543 rotate(elements, theAxis, theAngleInRadians,
4544 false, theCopyGroups, & mesh_i->GetImpl());
4545 mesh_i->CreateGroupServants();
4547 if ( !myIsPreviewMode ) {
4548 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4549 << theObject << ", "
4551 << TVar( theAngleInRadians ) << ", "
4552 << theCopyGroups << ", '"
4553 << theMeshName << "' )";
4558 if (!myIsPreviewMode && mesh_i)
4559 mesh_i->GetGroups();
4561 return mesh._retn();
4563 SMESH_CATCH( SMESH::throwCorbaException );
4567 //=======================================================================
4570 //=======================================================================
4572 SMESH::ListOfGroups*
4573 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4574 const SMESH::PointStruct& thePoint,
4575 const SMESH::double_array& theScaleFact,
4576 CORBA::Boolean theCopy,
4578 ::SMESH_Mesh* theTargetMesh)
4579 throw (SALOME::SALOME_Exception)
4583 if ( theScaleFact.length() < 1 )
4584 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4585 if ( theScaleFact.length() == 2 )
4586 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4588 if ( theTargetMesh )
4591 TIDSortedElemSet elements;
4592 prepareIdSource( theObject );
4593 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4594 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4599 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4600 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4602 double tol = std::numeric_limits<double>::max();
4604 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4605 0, S[1], 0, thePoint.y * (1-S[1]),
4606 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4608 TIDSortedElemSet copyElements;
4609 TIDSortedElemSet* workElements = &elements;
4610 if ( myIsPreviewMode )
4612 TPreviewMesh * tmpMesh = getPreviewMesh();
4613 tmpMesh->Copy( elements, copyElements);
4614 if ( !theCopy && !theTargetMesh )
4616 TIDSortedElemSet elemsAround, elemsAroundCopy;
4617 getElementsAround( elements, getMeshDS(), elemsAround );
4618 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4620 workElements = & copyElements;
4621 theMakeGroups = false;
4624 ::SMESH_MeshEditor::PGroupIDs groupIds =
4625 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4627 if ( theCopy && !myIsPreviewMode )
4629 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4630 else declareMeshModified( /*isReComputeSafe=*/false );
4632 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4634 SMESH_CATCH( SMESH::throwCorbaException );
4638 //=======================================================================
4641 //=======================================================================
4643 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4644 const SMESH::PointStruct& thePoint,
4645 const SMESH::double_array& theScaleFact,
4646 CORBA::Boolean theCopy)
4647 throw (SALOME::SALOME_Exception)
4649 if ( !myIsPreviewMode ) {
4650 TPythonDump() << this << ".Scale( "
4651 << theObject << ", "
4653 << TVar( theScaleFact ) << ", "
4656 scale(theObject, thePoint, theScaleFact, theCopy, false);
4660 //=======================================================================
4661 //function : ScaleMakeGroups
4663 //=======================================================================
4665 SMESH::ListOfGroups*
4666 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4667 const SMESH::PointStruct& thePoint,
4668 const SMESH::double_array& theScaleFact)
4669 throw (SALOME::SALOME_Exception)
4671 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4673 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4674 if (!myIsPreviewMode) {
4675 dumpGroupsList(aPythonDump, aGroups);
4676 aPythonDump << this << ".Scale("
4679 << TVar( theScaleFact ) << ",True,True)";
4685 //=======================================================================
4686 //function : ScaleMakeMesh
4688 //=======================================================================
4690 SMESH::SMESH_Mesh_ptr
4691 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4692 const SMESH::PointStruct& thePoint,
4693 const SMESH::double_array& theScaleFact,
4694 CORBA::Boolean theCopyGroups,
4695 const char* theMeshName)
4696 throw (SALOME::SALOME_Exception)
4698 SMESH_Mesh_i* mesh_i;
4699 SMESH::SMESH_Mesh_var mesh;
4700 { // open new scope to dump "MakeMesh" command
4701 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4703 TPythonDump pydump; // to prevent dump at mesh creation
4704 mesh = makeMesh( theMeshName );
4705 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4709 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4710 mesh_i->CreateGroupServants();
4712 if ( !myIsPreviewMode )
4713 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4714 << theObject << ", "
4716 << TVar( theScaleFact ) << ", "
4717 << theCopyGroups << ", '"
4718 << theMeshName << "' )";
4722 if (!myIsPreviewMode && mesh_i)
4723 mesh_i->GetGroups();
4725 return mesh._retn();
4729 //=======================================================================
4730 //function : FindCoincidentNodes
4732 //=======================================================================
4734 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4735 SMESH::array_of_long_array_out GroupsOfNodes)
4736 throw (SALOME::SALOME_Exception)
4741 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4742 TIDSortedNodeSet nodes; // no input nodes
4743 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4745 GroupsOfNodes = new SMESH::array_of_long_array;
4746 GroupsOfNodes->length( aListOfListOfNodes.size() );
4747 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4748 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4749 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4750 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4751 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4752 aGroup.length( aListOfNodes.size() );
4753 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4754 aGroup[ j ] = (*lIt)->GetID();
4756 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4757 << Tolerance << " )";
4759 SMESH_CATCH( SMESH::throwCorbaException );
4762 //=======================================================================
4763 //function : FindCoincidentNodesOnPart
4765 //=======================================================================
4767 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4768 CORBA::Double Tolerance,
4769 SMESH::array_of_long_array_out GroupsOfNodes)
4770 throw (SALOME::SALOME_Exception)
4775 TIDSortedNodeSet nodes;
4776 prepareIdSource( theObject );
4777 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4779 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4781 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4783 GroupsOfNodes = new SMESH::array_of_long_array;
4784 GroupsOfNodes->length( aListOfListOfNodes.size() );
4785 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4786 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4788 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4789 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4790 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4791 aGroup.length( aListOfNodes.size() );
4792 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4793 aGroup[ j ] = (*lIt)->GetID();
4795 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4797 << Tolerance << " )";
4799 SMESH_CATCH( SMESH::throwCorbaException );
4802 //================================================================================
4804 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4805 * ExceptSubMeshOrGroups
4807 //================================================================================
4809 void SMESH_MeshEditor_i::
4810 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4811 CORBA::Double theTolerance,
4812 SMESH::array_of_long_array_out theGroupsOfNodes,
4813 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4814 throw (SALOME::SALOME_Exception)
4819 TIDSortedNodeSet nodes;
4820 prepareIdSource( theObject );
4821 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4823 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4825 TIDSortedNodeSet exceptNodes;
4826 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
4827 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4828 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4829 nodes.erase( *avoidNode );
4831 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4833 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4835 theGroupsOfNodes = new SMESH::array_of_long_array;
4836 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4837 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4838 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4840 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4841 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4842 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4843 aGroup.length( aListOfNodes.size() );
4844 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4845 aGroup[ j ] = (*lIt)->GetID();
4847 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4849 << theTolerance << ", "
4850 << theExceptSubMeshOrGroups << " )";
4852 SMESH_CATCH( SMESH::throwCorbaException );
4855 //=======================================================================
4856 //function : MergeNodes
4858 //=======================================================================
4860 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4861 throw (SALOME::SALOME_Exception)
4866 SMESHDS_Mesh* aMesh = getMeshDS();
4868 TPythonDump aTPythonDump;
4869 aTPythonDump << this << ".MergeNodes([";
4870 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4871 for (int i = 0; i < GroupsOfNodes.length(); i++)
4873 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4874 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4875 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4876 for ( int j = 0; j < aNodeGroup.length(); j++ )
4878 CORBA::Long index = aNodeGroup[ j ];
4879 const SMDS_MeshNode * node = aMesh->FindNode(index);
4881 aListOfNodes.push_back( node );
4883 if ( aListOfNodes.size() < 2 )
4884 aListOfListOfNodes.pop_back();
4886 if ( i > 0 ) aTPythonDump << ", ";
4887 aTPythonDump << aNodeGroup;
4889 getEditor().MergeNodes( aListOfListOfNodes );
4891 aTPythonDump << "])";
4893 declareMeshModified( /*isReComputeSafe=*/false );
4895 SMESH_CATCH( SMESH::throwCorbaException );
4898 //=======================================================================
4899 //function : FindEqualElements
4901 //=======================================================================
4903 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4904 SMESH::array_of_long_array_out GroupsOfElementsID)
4905 throw (SALOME::SALOME_Exception)
4910 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4911 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4913 TIDSortedElemSet elems;
4914 prepareIdSource( theObject );
4915 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4917 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4918 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
4920 GroupsOfElementsID = new SMESH::array_of_long_array;
4921 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4923 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4924 aListOfListOfElementsID.begin();
4925 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4927 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4928 list<int>& listOfIDs = *arraysIt;
4929 aGroup.length( listOfIDs.size() );
4930 list<int>::iterator idIt = listOfIDs.begin();
4931 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4932 aGroup[ k ] = *idIt;
4935 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4939 SMESH_CATCH( SMESH::throwCorbaException );
4942 //=======================================================================
4943 //function : MergeElements
4945 //=======================================================================
4947 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4948 throw (SALOME::SALOME_Exception)
4953 TPythonDump aTPythonDump;
4954 aTPythonDump << this << ".MergeElements( [";
4956 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4958 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4959 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4960 aListOfListOfElementsID.push_back( list< int >() );
4961 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4962 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4963 CORBA::Long id = anElemsIDGroup[ j ];
4964 aListOfElemsID.push_back( id );
4966 if ( aListOfElemsID.size() < 2 )
4967 aListOfListOfElementsID.pop_back();
4968 if ( i > 0 ) aTPythonDump << ", ";
4969 aTPythonDump << anElemsIDGroup;
4972 getEditor().MergeElements(aListOfListOfElementsID);
4974 declareMeshModified( /*isReComputeSafe=*/true );
4976 aTPythonDump << "] )";
4978 SMESH_CATCH( SMESH::throwCorbaException );
4981 //=======================================================================
4982 //function : MergeEqualElements
4984 //=======================================================================
4986 void SMESH_MeshEditor_i::MergeEqualElements()
4987 throw (SALOME::SALOME_Exception)
4992 getEditor().MergeEqualElements();
4994 declareMeshModified( /*isReComputeSafe=*/true );
4996 TPythonDump() << this << ".MergeEqualElements()";
4998 SMESH_CATCH( SMESH::throwCorbaException );
5001 //=============================================================================
5003 * Move the node to a given point
5005 //=============================================================================
5007 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
5011 throw (SALOME::SALOME_Exception)
5014 initData(/*deleteSearchers=*/false);
5016 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
5020 if ( theNodeSearcher )
5021 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5023 if ( myIsPreviewMode ) // make preview data
5025 // in a preview mesh, make edges linked to a node
5026 TPreviewMesh& tmpMesh = *getPreviewMesh();
5027 TIDSortedElemSet linkedNodes;
5028 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5029 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5030 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
5031 for ( ; nIt != linkedNodes.end(); ++nIt )
5033 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
5034 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
5038 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
5039 // fill preview data
5041 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5042 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5044 getMeshDS()->MoveNode(node, x, y, z);
5046 if ( !myIsPreviewMode )
5048 // Update Python script
5049 TPythonDump() << "isDone = " << this << ".MoveNode( "
5050 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
5051 declareMeshModified( /*isReComputeSafe=*/false );
5054 SMESH_CATCH( SMESH::throwCorbaException );
5059 //================================================================================
5061 * \brief Return ID of node closest to a given point
5063 //================================================================================
5065 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
5068 throw (SALOME::SALOME_Exception)
5071 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5073 if ( !theNodeSearcher ) {
5074 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5077 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
5078 return node->GetID();
5080 SMESH_CATCH( SMESH::throwCorbaException );
5084 //================================================================================
5086 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
5087 * move the node closest to the point to point's location and return ID of the node
5089 //================================================================================
5091 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
5094 CORBA::Long theNodeID)
5095 throw (SALOME::SALOME_Exception)
5098 // We keep theNodeSearcher until any mesh modification:
5099 // 1) initData() deletes theNodeSearcher at any edition,
5100 // 2) TSearchersDeleter - at any mesh compute event and mesh change
5102 initData(/*deleteSearchers=*/false);
5104 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5106 int nodeID = theNodeID;
5107 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
5108 if ( !node ) // preview moving node
5110 if ( !theNodeSearcher ) {
5111 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5114 node = theNodeSearcher->FindClosestTo( p );
5117 nodeID = node->GetID();
5118 if ( myIsPreviewMode ) // make preview data
5120 // in a preview mesh, make edges linked to a node
5121 TPreviewMesh tmpMesh = *getPreviewMesh();
5122 TIDSortedElemSet linkedNodes;
5123 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5124 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5125 for ( ; nIt != linkedNodes.end(); ++nIt )
5127 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
5128 tmpMesh.Copy( &edge );
5131 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
5133 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
5134 // fill preview data
5136 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5138 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5142 getMeshDS()->MoveNode(node, x, y, z);
5146 if ( !myIsPreviewMode )
5148 TPythonDump() << "nodeID = " << this
5149 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
5150 << ", " << nodeID << " )";
5152 declareMeshModified( /*isReComputeSafe=*/false );
5157 SMESH_CATCH( SMESH::throwCorbaException );
5161 //=======================================================================
5163 * Return elements of given type where the given point is IN or ON.
5165 * 'ALL' type means elements of any type excluding nodes
5167 //=======================================================================
5169 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
5172 SMESH::ElementType type)
5173 throw (SALOME::SALOME_Exception)
5176 SMESH::long_array_var res = new SMESH::long_array;
5177 vector< const SMDS_MeshElement* > foundElems;
5179 theSearchersDeleter.Set( myMesh );
5180 if ( !theElementSearcher ) {
5181 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5183 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5184 SMDSAbs_ElementType( type ),
5186 res->length( foundElems.size() );
5187 for ( int i = 0; i < foundElems.size(); ++i )
5188 res[i] = foundElems[i]->GetID();
5190 if ( !myIsPreviewMode ) // call from tui
5191 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
5199 SMESH_CATCH( SMESH::throwCorbaException );
5203 //=======================================================================
5204 //function : FindAmongElementsByPoint
5205 //purpose : Searching among the given elements, return elements of given type
5206 // where the given point is IN or ON.
5207 // 'ALL' type means elements of any type excluding nodes
5208 //=======================================================================
5211 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
5215 SMESH::ElementType type)
5216 throw (SALOME::SALOME_Exception)
5219 SMESH::long_array_var res = new SMESH::long_array;
5221 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
5222 if ( types->length() == 1 && // a part contains only nodes or 0D elements
5223 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
5224 type != types[0] ) // but search of elements of dim > 0
5227 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
5228 return FindElementsByPoint( x,y,z, type );
5230 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
5232 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
5233 if ( !theElementSearcher )
5235 // create a searcher from elementIDs
5236 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
5237 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
5239 if ( !idSourceToSet( elementIDs, meshDS, elements,
5240 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
5243 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5244 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
5246 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
5249 vector< const SMDS_MeshElement* > foundElems;
5251 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5252 SMDSAbs_ElementType( type ),
5254 res->length( foundElems.size() );
5255 for ( int i = 0; i < foundElems.size(); ++i )
5256 res[i] = foundElems[i]->GetID();
5258 if ( !myIsPreviewMode ) // call from tui
5259 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
5260 << elementIDs << ", "
5268 SMESH_CATCH( SMESH::throwCorbaException );
5272 //=======================================================================
5273 //function : GetPointState
5274 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
5275 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
5276 //=======================================================================
5278 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
5281 throw (SALOME::SALOME_Exception)
5284 theSearchersDeleter.Set( myMesh );
5285 if ( !theElementSearcher ) {
5286 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5288 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
5290 SMESH_CATCH( SMESH::throwCorbaException );
5294 //=======================================================================
5295 //function : convError
5297 //=======================================================================
5299 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
5301 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
5305 RETCASE( SEW_BORDER1_NOT_FOUND );
5306 RETCASE( SEW_BORDER2_NOT_FOUND );
5307 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
5308 RETCASE( SEW_BAD_SIDE_NODES );
5309 RETCASE( SEW_VOLUMES_TO_SPLIT );
5310 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
5311 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
5312 RETCASE( SEW_BAD_SIDE1_NODES );
5313 RETCASE( SEW_BAD_SIDE2_NODES );
5315 return SMESH::SMESH_MeshEditor::SEW_OK;
5318 //=======================================================================
5319 //function : SewFreeBorders
5321 //=======================================================================
5323 SMESH::SMESH_MeshEditor::Sew_Error
5324 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
5325 CORBA::Long SecondNodeID1,
5326 CORBA::Long LastNodeID1,
5327 CORBA::Long FirstNodeID2,
5328 CORBA::Long SecondNodeID2,
5329 CORBA::Long LastNodeID2,
5330 CORBA::Boolean CreatePolygons,
5331 CORBA::Boolean CreatePolyedrs)
5332 throw (SALOME::SALOME_Exception)
5337 SMESHDS_Mesh* aMesh = getMeshDS();
5339 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5340 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5341 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5342 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5343 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5344 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
5346 if (!aBorderFirstNode ||
5347 !aBorderSecondNode||
5349 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5350 if (!aSide2FirstNode ||
5351 !aSide2SecondNode ||
5353 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5355 TPythonDump() << "error = " << this << ".SewFreeBorders( "
5356 << FirstNodeID1 << ", "
5357 << SecondNodeID1 << ", "
5358 << LastNodeID1 << ", "
5359 << FirstNodeID2 << ", "
5360 << SecondNodeID2 << ", "
5361 << LastNodeID2 << ", "
5362 << CreatePolygons<< ", "
5363 << CreatePolyedrs<< " )";
5365 SMESH::SMESH_MeshEditor::Sew_Error error =
5366 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5377 declareMeshModified( /*isReComputeSafe=*/false );
5380 SMESH_CATCH( SMESH::throwCorbaException );
5381 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5385 //=======================================================================
5386 //function : SewConformFreeBorders
5388 //=======================================================================
5390 SMESH::SMESH_MeshEditor::Sew_Error
5391 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
5392 CORBA::Long SecondNodeID1,
5393 CORBA::Long LastNodeID1,
5394 CORBA::Long FirstNodeID2,
5395 CORBA::Long SecondNodeID2)
5396 throw (SALOME::SALOME_Exception)
5401 SMESHDS_Mesh* aMesh = getMeshDS();
5403 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5404 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5405 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5406 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5407 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5408 const SMDS_MeshNode* aSide2ThirdNode = 0;
5410 if (!aBorderFirstNode ||
5411 !aBorderSecondNode||
5413 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5414 if (!aSide2FirstNode ||
5416 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5418 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
5419 << FirstNodeID1 << ", "
5420 << SecondNodeID1 << ", "
5421 << LastNodeID1 << ", "
5422 << FirstNodeID2 << ", "
5423 << SecondNodeID2 << " )";
5425 SMESH::SMESH_MeshEditor::Sew_Error error =
5426 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5435 declareMeshModified( /*isReComputeSafe=*/false );
5438 SMESH_CATCH( SMESH::throwCorbaException );
5439 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5443 //=======================================================================
5444 //function : SewBorderToSide
5446 //=======================================================================
5448 SMESH::SMESH_MeshEditor::Sew_Error
5449 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5450 CORBA::Long SecondNodeIDOnFreeBorder,
5451 CORBA::Long LastNodeIDOnFreeBorder,
5452 CORBA::Long FirstNodeIDOnSide,
5453 CORBA::Long LastNodeIDOnSide,
5454 CORBA::Boolean CreatePolygons,
5455 CORBA::Boolean CreatePolyedrs)
5456 throw (SALOME::SALOME_Exception)
5461 SMESHDS_Mesh* aMesh = getMeshDS();
5463 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5464 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5465 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5466 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5467 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5468 const SMDS_MeshNode* aSide2ThirdNode = 0;
5470 if (!aBorderFirstNode ||
5471 !aBorderSecondNode||
5473 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5474 if (!aSide2FirstNode ||
5476 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5478 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5479 << FirstNodeIDOnFreeBorder << ", "
5480 << SecondNodeIDOnFreeBorder << ", "
5481 << LastNodeIDOnFreeBorder << ", "
5482 << FirstNodeIDOnSide << ", "
5483 << LastNodeIDOnSide << ", "
5484 << CreatePolygons << ", "
5485 << CreatePolyedrs << ") ";
5487 SMESH::SMESH_MeshEditor::Sew_Error error =
5488 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5498 declareMeshModified( /*isReComputeSafe=*/false );
5501 SMESH_CATCH( SMESH::throwCorbaException );
5502 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5506 //=======================================================================
5507 //function : SewSideElements
5509 //=======================================================================
5511 SMESH::SMESH_MeshEditor::Sew_Error
5512 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5513 const SMESH::long_array& IDsOfSide2Elements,
5514 CORBA::Long NodeID1OfSide1ToMerge,
5515 CORBA::Long NodeID1OfSide2ToMerge,
5516 CORBA::Long NodeID2OfSide1ToMerge,
5517 CORBA::Long NodeID2OfSide2ToMerge)
5518 throw (SALOME::SALOME_Exception)
5523 SMESHDS_Mesh* aMesh = getMeshDS();
5525 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5526 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5527 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5528 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5530 if (!aFirstNode1ToMerge ||
5531 !aFirstNode2ToMerge )
5532 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5533 if (!aSecondNode1ToMerge||
5534 !aSecondNode2ToMerge)
5535 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5537 TIDSortedElemSet aSide1Elems, aSide2Elems;
5538 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5539 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5541 TPythonDump() << "error = " << this << ".SewSideElements( "
5542 << IDsOfSide1Elements << ", "
5543 << IDsOfSide2Elements << ", "
5544 << NodeID1OfSide1ToMerge << ", "
5545 << NodeID1OfSide2ToMerge << ", "
5546 << NodeID2OfSide1ToMerge << ", "
5547 << NodeID2OfSide2ToMerge << ")";
5549 SMESH::SMESH_MeshEditor::Sew_Error error =
5550 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5553 aSecondNode1ToMerge,
5554 aSecondNode2ToMerge));
5556 declareMeshModified( /*isReComputeSafe=*/false );
5559 SMESH_CATCH( SMESH::throwCorbaException );
5560 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5563 //================================================================================
5565 * \brief Set new nodes for given element
5566 * \param ide - element id
5567 * \param newIDs - new node ids
5568 * \retval CORBA::Boolean - true if result is OK
5570 //================================================================================
5572 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5573 const SMESH::long_array& newIDs)
5574 throw (SALOME::SALOME_Exception)
5579 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5580 if(!elem) return false;
5582 int nbn = newIDs.length();
5584 vector<const SMDS_MeshNode*> aNodes(nbn);
5587 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5590 aNodes[nbn1] = aNode;
5593 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5594 << ide << ", " << newIDs << " )";
5596 MESSAGE("ChangeElementNodes");
5597 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5599 declareMeshModified( /*isReComputeSafe=*/ !res );
5603 SMESH_CATCH( SMESH::throwCorbaException );
5607 //=======================================================================
5609 * \brief Makes a part of the mesh quadratic or bi-quadratic
5611 //=======================================================================
5613 void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d,
5614 CORBA::Boolean theToBiQuad,
5615 SMESH::SMESH_IDSource_ptr theObject)
5616 throw (SALOME::SALOME_Exception)
5619 TIDSortedElemSet elems;
5621 if ( !( elemsOK = CORBA::is_nil( theObject )))
5623 prepareIdSource( theObject );
5624 elemsOK = idSourceToSet( theObject, getMeshDS(), elems,
5625 SMDSAbs_All, /*emptyIfIsMesh=*/true );
5629 if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
5630 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5632 if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
5633 else getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
5635 declareMeshModified( /*isReComputeSafe=*/false );
5638 SMESH_CATCH( SMESH::throwCorbaException );
5641 //=======================================================================
5642 //function : ConvertFromQuadratic
5644 //=======================================================================
5646 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5647 throw (SALOME::SALOME_Exception)
5649 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5650 TPythonDump() << this << ".ConvertFromQuadratic()";
5651 declareMeshModified( /*isReComputeSafe=*/!isDone );
5655 //=======================================================================
5656 //function : ConvertToQuadratic
5658 //=======================================================================
5660 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5661 throw (SALOME::SALOME_Exception)
5663 convertToQuadratic( theForce3d, false );
5664 TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
5667 //================================================================================
5669 * \brief Makes a part of the mesh quadratic
5671 //================================================================================
5673 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5674 SMESH::SMESH_IDSource_ptr theObject)
5675 throw (SALOME::SALOME_Exception)
5677 convertToQuadratic( theForce3d, false, theObject );
5678 TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
5681 //================================================================================
5683 * \brief Makes a part of the mesh bi-quadratic
5685 //================================================================================
5687 void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean theForce3d,
5688 SMESH::SMESH_IDSource_ptr theObject)
5689 throw (SALOME::SALOME_Exception)
5691 convertToQuadratic( theForce3d, true, theObject );
5692 TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
5695 //================================================================================
5697 * \brief Makes a part of the mesh linear
5699 //================================================================================
5701 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5702 throw (SALOME::SALOME_Exception)
5708 TIDSortedElemSet elems;
5709 prepareIdSource( theObject );
5710 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5712 if ( elems.empty() )
5714 ConvertFromQuadratic();
5716 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5718 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5722 getEditor().ConvertFromQuadratic(elems);
5725 declareMeshModified( /*isReComputeSafe=*/false );
5727 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5729 SMESH_CATCH( SMESH::throwCorbaException );
5732 //=======================================================================
5733 //function : makeMesh
5734 //purpose : create a named imported mesh
5735 //=======================================================================
5737 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5739 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5740 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5741 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5742 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5743 gen->SetName( meshSO, theMeshName, "Mesh" );
5744 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5746 return mesh._retn();
5749 //=======================================================================
5750 //function : dumpGroupsList
5752 //=======================================================================
5754 void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPython,
5755 const SMESH::ListOfGroups * theGroupList)
5757 bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
5758 if ( isDumpGroupList )
5759 theDumpPython << theGroupList << " = ";
5762 //================================================================================
5764 \brief Generates the unique group name.
5765 \param thePrefix name prefix
5768 //================================================================================
5770 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5772 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5773 set<string> groupNames;
5775 // Get existing group names
5776 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5777 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5778 if (CORBA::is_nil(aGroup))
5781 CORBA::String_var name = aGroup->GetName();
5782 groupNames.insert( name.in() );
5786 string name = thePrefix;
5789 while (!groupNames.insert(name).second)
5790 name = SMESH_Comment( thePrefix ) << "_" << index++;
5795 //================================================================================
5797 * \brief Prepare SMESH_IDSource for work
5799 //================================================================================
5801 void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
5803 if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5805 SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
5806 filter->SetMesh( mesh );
5810 //================================================================================
5812 * \brief Duplicates given elements, i.e. creates new elements based on the
5813 * same nodes as the given ones.
5814 * \param theElements - container of elements to duplicate.
5815 * \param theGroupName - a name of group to contain the generated elements.
5816 * If a group with such a name already exists, the new elements
5817 * are added to the existng group, else a new group is created.
5818 * If \a theGroupName is empty, new elements are not added
5820 * \return a group where the new elements are added. NULL if theGroupName == "".
5823 //================================================================================
5825 SMESH::SMESH_Group_ptr
5826 SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
5827 const char* theGroupName)
5828 throw (SALOME::SALOME_Exception)
5830 SMESH::SMESH_Group_var newGroup;
5837 TIDSortedElemSet elems;
5838 prepareIdSource( theElements );
5839 if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
5841 getEditor().DoubleElements( elems );
5843 if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
5846 SMESH::ElementType type =
5847 SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
5848 // find existing group
5849 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5850 for ( size_t i = 0; i < groups->length(); ++i )
5851 if ( groups[i]->GetType() == type )
5853 CORBA::String_var name = groups[i]->GetName();
5854 if ( strcmp( name, theGroupName ) == 0 ) {
5855 newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
5859 // create a new group
5860 if ( newGroup->_is_nil() )
5861 newGroup = myMesh_i->CreateGroup( type, theGroupName );
5863 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
5865 SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
5866 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
5867 for ( int i = 1; i <= aSeq.Length(); i++ )
5868 groupDS->SMDSGroup().Add( aSeq(i) );
5873 if ( !newGroup->_is_nil() )
5874 pyDump << newGroup << " = ";
5875 pyDump << this << ".DoubleElements( "
5876 << theElements << ", " << "'" << theGroupName <<"')";
5878 SMESH_CATCH( SMESH::throwCorbaException );
5880 return newGroup._retn();
5883 //================================================================================
5885 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5886 \param theNodes - identifiers of nodes to be doubled
5887 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5888 nodes. If list of element identifiers is empty then nodes are doubled but
5889 they not assigned to elements
5890 \return TRUE if operation has been completed successfully, FALSE otherwise
5891 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5893 //================================================================================
5895 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5896 const SMESH::long_array& theModifiedElems )
5897 throw (SALOME::SALOME_Exception)
5902 list< int > aListOfNodes;
5904 for ( i = 0, n = theNodes.length(); i < n; i++ )
5905 aListOfNodes.push_back( theNodes[ i ] );
5907 list< int > aListOfElems;
5908 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5909 aListOfElems.push_back( theModifiedElems[ i ] );
5911 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
5913 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5915 // Update Python script
5916 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5920 SMESH_CATCH( SMESH::throwCorbaException );
5924 //================================================================================
5926 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5927 This method provided for convenience works as DoubleNodes() described above.
5928 \param theNodeId - identifier of node to be doubled.
5929 \param theModifiedElems - identifiers of elements to be updated.
5930 \return TRUE if operation has been completed successfully, FALSE otherwise
5931 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5933 //================================================================================
5935 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5936 const SMESH::long_array& theModifiedElems )
5937 throw (SALOME::SALOME_Exception)
5940 SMESH::long_array_var aNodes = new SMESH::long_array;
5941 aNodes->length( 1 );
5942 aNodes[ 0 ] = theNodeId;
5944 TPythonDump pyDump; // suppress dump by the next line
5946 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5948 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5952 SMESH_CATCH( SMESH::throwCorbaException );
5956 //================================================================================
5958 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5959 This method provided for convenience works as DoubleNodes() described above.
5960 \param theNodes - group of nodes to be doubled.
5961 \param theModifiedElems - group of elements to be updated.
5962 \return TRUE if operation has been completed successfully, FALSE otherwise
5963 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5965 //================================================================================
5967 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5968 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5969 throw (SALOME::SALOME_Exception)
5972 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5975 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5976 SMESH::long_array_var aModifiedElems;
5977 if ( !CORBA::is_nil( theModifiedElems ) )
5978 aModifiedElems = theModifiedElems->GetListOfID();
5981 aModifiedElems = new SMESH::long_array;
5982 aModifiedElems->length( 0 );
5985 TPythonDump pyDump; // suppress dump by the next line
5987 bool done = DoubleNodes( aNodes, aModifiedElems );
5989 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5993 SMESH_CATCH( SMESH::throwCorbaException );
5997 //================================================================================
5999 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6000 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
6001 * \param theNodes - group of nodes to be doubled.
6002 * \param theModifiedElems - group of elements to be updated.
6003 * \return a new group with newly created nodes
6004 * \sa DoubleNodeGroup()
6006 //================================================================================
6008 SMESH::SMESH_Group_ptr
6009 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
6010 SMESH::SMESH_GroupBase_ptr theModifiedElems )
6011 throw (SALOME::SALOME_Exception)
6014 SMESH::SMESH_Group_var aNewGroup;
6016 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
6017 return aNewGroup._retn();
6020 SMESH::long_array_var aNodes = theNodes->GetListOfID();
6021 SMESH::long_array_var aModifiedElems;
6022 if ( !CORBA::is_nil( theModifiedElems ) )
6023 aModifiedElems = theModifiedElems->GetListOfID();
6025 aModifiedElems = new SMESH::long_array;
6026 aModifiedElems->length( 0 );
6029 TPythonDump pyDump; // suppress dump by the next line
6031 bool aResult = DoubleNodes( aNodes, aModifiedElems );
6034 // Create group with newly created nodes
6035 SMESH::long_array_var anIds = GetLastCreatedNodes();
6036 if (anIds->length() > 0) {
6037 string anUnindexedName (theNodes->GetName());
6038 string aNewName = generateGroupName(anUnindexedName + "_double");
6039 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6040 aNewGroup->Add(anIds);
6041 pyDump << aNewGroup << " = ";
6045 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
6046 << theModifiedElems << " )";
6048 return aNewGroup._retn();
6050 SMESH_CATCH( SMESH::throwCorbaException );
6054 //================================================================================
6056 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6057 This method provided for convenience works as DoubleNodes() described above.
6058 \param theNodes - list of groups of nodes to be doubled
6059 \param theModifiedElems - list of groups of elements to be updated.
6060 \return TRUE if operation has been completed successfully, FALSE otherwise
6061 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
6063 //================================================================================
6065 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
6066 const SMESH::ListOfGroups& theModifiedElems )
6067 throw (SALOME::SALOME_Exception)
6072 std::list< int > aNodes;
6074 for ( i = 0, n = theNodes.length(); i < n; i++ )
6076 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
6077 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
6079 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6080 for ( j = 0, m = aCurr->length(); j < m; j++ )
6081 aNodes.push_back( aCurr[ j ] );
6085 std::list< int > anElems;
6086 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
6088 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
6089 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
6091 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6092 for ( j = 0, m = aCurr->length(); j < m; j++ )
6093 anElems.push_back( aCurr[ j ] );
6097 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
6099 declareMeshModified( /*isReComputeSafe=*/false );
6101 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
6105 SMESH_CATCH( SMESH::throwCorbaException );
6109 //================================================================================
6111 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6112 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
6113 * \param theNodes - group of nodes to be doubled.
6114 * \param theModifiedElems - group of elements to be updated.
6115 * \return a new group with newly created nodes
6116 * \sa DoubleNodeGroups()
6118 //================================================================================
6120 SMESH::SMESH_Group_ptr
6121 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
6122 const SMESH::ListOfGroups& theModifiedElems )
6123 throw (SALOME::SALOME_Exception)
6125 SMESH::SMESH_Group_var aNewGroup;
6127 TPythonDump pyDump; // suppress dump by the next line
6129 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
6133 // Create group with newly created nodes
6134 SMESH::long_array_var anIds = GetLastCreatedNodes();
6135 if (anIds->length() > 0) {
6136 string anUnindexedName (theNodes[0]->GetName());
6137 string aNewName = generateGroupName(anUnindexedName + "_double");
6138 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6139 aNewGroup->Add(anIds);
6140 pyDump << aNewGroup << " = ";
6144 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
6145 << theModifiedElems << " )";
6147 return aNewGroup._retn();
6151 //================================================================================
6153 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6154 \param theElems - the list of elements (edges or faces) to be replicated
6155 The nodes for duplication could be found from these elements
6156 \param theNodesNot - list of nodes to NOT replicate
6157 \param theAffectedElems - the list of elements (cells and edges) to which the
6158 replicated nodes should be associated to.
6159 \return TRUE if operation has been completed successfully, FALSE otherwise
6160 \sa DoubleNodeGroup(), DoubleNodeGroups()
6162 //================================================================================
6164 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
6165 const SMESH::long_array& theNodesNot,
6166 const SMESH::long_array& theAffectedElems )
6167 throw (SALOME::SALOME_Exception)
6172 SMESHDS_Mesh* aMeshDS = getMeshDS();
6173 TIDSortedElemSet anElems, aNodes, anAffected;
6174 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6175 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6176 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
6178 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6180 // Update Python script
6181 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
6182 << theNodesNot << ", " << theAffectedElems << " )";
6184 declareMeshModified( /*isReComputeSafe=*/false );
6187 SMESH_CATCH( SMESH::throwCorbaException );
6191 //================================================================================
6193 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6194 \param theElems - the list of elements (edges or faces) to be replicated
6195 The nodes for duplication could be found from these elements
6196 \param theNodesNot - list of nodes to NOT replicate
6197 \param theShape - shape to detect affected elements (element which geometric center
6198 located on or inside shape).
6199 The replicated nodes should be associated to affected elements.
6200 \return TRUE if operation has been completed successfully, FALSE otherwise
6201 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
6203 //================================================================================
6205 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
6206 const SMESH::long_array& theNodesNot,
6207 GEOM::GEOM_Object_ptr theShape )
6208 throw (SALOME::SALOME_Exception)
6214 SMESHDS_Mesh* aMeshDS = getMeshDS();
6215 TIDSortedElemSet anElems, aNodes;
6216 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6217 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6219 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6220 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6222 // Update Python script
6223 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
6224 << theNodesNot << ", " << theShape << " )";
6226 declareMeshModified( /*isReComputeSafe=*/false );
6229 SMESH_CATCH( SMESH::throwCorbaException );
6233 //================================================================================
6235 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6236 \param theElems - group of of elements (edges or faces) to be replicated
6237 \param theNodesNot - group of nodes not to replicated
6238 \param theAffectedElems - group of elements to which the replicated nodes
6239 should be associated to.
6240 \return TRUE if operation has been completed successfully, FALSE otherwise
6241 \sa DoubleNodes(), DoubleNodeGroups()
6243 //================================================================================
6246 SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
6247 SMESH::SMESH_GroupBase_ptr theNodesNot,
6248 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6249 throw (SALOME::SALOME_Exception)
6252 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6258 SMESHDS_Mesh* aMeshDS = getMeshDS();
6259 TIDSortedElemSet anElems, aNodes, anAffected;
6260 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6261 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6262 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6264 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6266 // Update Python script
6267 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
6268 << theNodesNot << ", " << theAffectedElems << " )";
6270 declareMeshModified( /*isReComputeSafe=*/false );
6273 SMESH_CATCH( SMESH::throwCorbaException );
6277 //================================================================================
6279 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6280 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6281 * \param theElems - group of of elements (edges or faces) to be replicated
6282 * \param theNodesNot - group of nodes not to replicated
6283 * \param theAffectedElems - group of elements to which the replicated nodes
6284 * should be associated to.
6285 * \return a new group with newly created elements
6286 * \sa DoubleNodeElemGroup()
6288 //================================================================================
6290 SMESH::SMESH_Group_ptr
6291 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
6292 SMESH::SMESH_GroupBase_ptr theNodesNot,
6293 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6294 throw (SALOME::SALOME_Exception)
6297 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
6301 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6302 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6304 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
6306 << theNodesNot << ", "
6307 << theAffectedElems << " )";
6309 return elemGroup._retn();
6312 //================================================================================
6314 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6315 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6316 * \param theElems - group of of elements (edges or faces) to be replicated
6317 * \param theNodesNot - group of nodes not to replicated
6318 * \param theAffectedElems - group of elements to which the replicated nodes
6319 * should be associated to.
6320 * \return a new group with newly created elements
6321 * \sa DoubleNodeElemGroup()
6323 //================================================================================
6325 SMESH::ListOfGroups*
6326 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
6327 SMESH::SMESH_GroupBase_ptr theNodesNot,
6328 SMESH::SMESH_GroupBase_ptr theAffectedElems,
6329 CORBA::Boolean theElemGroupNeeded,
6330 CORBA::Boolean theNodeGroupNeeded)
6331 throw (SALOME::SALOME_Exception)
6334 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6335 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6336 aTwoGroups->length( 2 );
6338 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6339 return aTwoGroups._retn();
6344 SMESHDS_Mesh* aMeshDS = getMeshDS();
6345 TIDSortedElemSet anElems, aNodes, anAffected;
6346 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6347 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6348 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6351 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6353 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6359 // Create group with newly created elements
6360 CORBA::String_var elemGroupName = theElems->GetName();
6361 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6362 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6364 SMESH::long_array_var anIds = GetLastCreatedElems();
6365 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6366 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6367 aNewElemGroup->Add(anIds);
6369 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6371 SMESH::long_array_var anIds = GetLastCreatedNodes();
6372 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6373 aNewNodeGroup->Add(anIds);
6377 // Update Python script
6380 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6381 else pyDump << aNewElemGroup << ", ";
6382 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6383 else pyDump << aNewNodeGroup << " ] = ";
6385 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
6386 << theNodesNot << ", "
6387 << theAffectedElems << ", "
6388 << theElemGroupNeeded << ", "
6389 << theNodeGroupNeeded <<" )";
6391 aTwoGroups[0] = aNewElemGroup._retn();
6392 aTwoGroups[1] = aNewNodeGroup._retn();
6393 return aTwoGroups._retn();
6395 SMESH_CATCH( SMESH::throwCorbaException );
6399 //================================================================================
6401 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6402 \param theElems - group of of elements (edges or faces) to be replicated
6403 \param theNodesNot - group of nodes not to replicated
6404 \param theShape - shape to detect affected elements (element which geometric center
6405 located on or inside shape).
6406 The replicated nodes should be associated to affected elements.
6407 \return TRUE if operation has been completed successfully, FALSE otherwise
6408 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
6410 //================================================================================
6413 SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
6414 SMESH::SMESH_GroupBase_ptr theNodesNot,
6415 GEOM::GEOM_Object_ptr theShape )
6416 throw (SALOME::SALOME_Exception)
6419 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6425 SMESHDS_Mesh* aMeshDS = getMeshDS();
6426 TIDSortedElemSet anElems, aNodes, anAffected;
6427 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6428 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6430 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6431 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6434 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6436 // Update Python script
6437 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
6438 << theNodesNot << ", " << theShape << " )";
6441 SMESH_CATCH( SMESH::throwCorbaException );
6445 //================================================================================
6447 * \brief Re-load elements from a list of groups into a TIDSortedElemSet
6448 * \param [in] theGrpList - groups
6449 * \param [in] theMeshDS - mesh
6450 * \param [out] theElemSet - set of elements
6451 * \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
6453 //================================================================================
6455 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
6456 SMESHDS_Mesh* theMeshDS,
6457 TIDSortedElemSet& theElemSet,
6458 const bool theIsNodeGrp)
6460 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
6462 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
6463 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
6464 : aGrp->GetType() != SMESH::NODE ) )
6466 SMESH::long_array_var anIDs = aGrp->GetIDs();
6467 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
6472 //================================================================================
6474 \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6475 This method provided for convenience works as DoubleNodes() described above.
6476 \param theElems - list of groups of elements (edges or faces) to be replicated
6477 \param theNodesNot - list of groups of nodes not to replicated
6478 \param theAffectedElems - group of elements to which the replicated nodes
6479 should be associated to.
6480 \return TRUE if operation has been completed successfully, FALSE otherwise
6481 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
6483 //================================================================================
6486 SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
6487 const SMESH::ListOfGroups& theNodesNot,
6488 const SMESH::ListOfGroups& theAffectedElems)
6489 throw (SALOME::SALOME_Exception)
6495 SMESHDS_Mesh* aMeshDS = getMeshDS();
6496 TIDSortedElemSet anElems, aNodes, anAffected;
6497 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6498 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6499 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6501 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6503 // Update Python script
6504 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
6505 << &theNodesNot << ", " << &theAffectedElems << " )";
6507 declareMeshModified( /*isReComputeSafe=*/false );
6510 SMESH_CATCH( SMESH::throwCorbaException );
6514 //================================================================================
6516 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6517 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6518 \param theElems - list of groups of elements (edges or faces) to be replicated
6519 \param theNodesNot - list of groups of nodes not to replicated
6520 \param theAffectedElems - group of elements to which the replicated nodes
6521 should be associated to.
6522 * \return a new group with newly created elements
6523 * \sa DoubleNodeElemGroups()
6525 //================================================================================
6527 SMESH::SMESH_Group_ptr
6528 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
6529 const SMESH::ListOfGroups& theNodesNot,
6530 const SMESH::ListOfGroups& theAffectedElems)
6531 throw (SALOME::SALOME_Exception)
6534 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
6538 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6539 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6541 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
6543 << theNodesNot << ", "
6544 << theAffectedElems << " )";
6546 return elemGroup._retn();
6549 //================================================================================
6551 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6552 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6553 \param theElems - list of groups of elements (edges or faces) to be replicated
6554 \param theNodesNot - list of groups of nodes not to replicated
6555 \param theAffectedElems - group of elements to which the replicated nodes
6556 should be associated to.
6557 * \return a new group with newly created elements
6558 * \sa DoubleNodeElemGroups()
6560 //================================================================================
6562 SMESH::ListOfGroups*
6563 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
6564 const SMESH::ListOfGroups& theNodesNot,
6565 const SMESH::ListOfGroups& theAffectedElems,
6566 CORBA::Boolean theElemGroupNeeded,
6567 CORBA::Boolean theNodeGroupNeeded)
6568 throw (SALOME::SALOME_Exception)
6571 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6572 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6573 aTwoGroups->length( 2 );
6578 SMESHDS_Mesh* aMeshDS = getMeshDS();
6579 TIDSortedElemSet anElems, aNodes, anAffected;
6580 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6581 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6582 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6584 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6586 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6591 // Create group with newly created elements
6592 CORBA::String_var elemGroupName = theElems[0]->GetName();
6593 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6594 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6596 SMESH::long_array_var anIds = GetLastCreatedElems();
6597 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6598 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6599 aNewElemGroup->Add(anIds);
6601 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6603 SMESH::long_array_var anIds = GetLastCreatedNodes();
6604 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6605 aNewNodeGroup->Add(anIds);
6609 // Update Python script
6612 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6613 else pyDump << aNewElemGroup << ", ";
6614 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6615 else pyDump << aNewNodeGroup << " ] = ";
6617 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6618 << &theNodesNot << ", "
6619 << &theAffectedElems << ", "
6620 << theElemGroupNeeded << ", "
6621 << theNodeGroupNeeded << " )";
6623 aTwoGroups[0] = aNewElemGroup._retn();
6624 aTwoGroups[1] = aNewNodeGroup._retn();
6625 return aTwoGroups._retn();
6627 SMESH_CATCH( SMESH::throwCorbaException );
6631 //================================================================================
6633 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6634 This method provided for convenience works as DoubleNodes() described above.
6635 \param theElems - list of groups of elements (edges or faces) to be replicated
6636 \param theNodesNot - list of groups of nodes not to replicated
6637 \param theShape - shape to detect affected elements (element which geometric center
6638 located on or inside shape).
6639 The replicated nodes should be associated to affected elements.
6640 \return TRUE if operation has been completed successfully, FALSE otherwise
6641 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6643 //================================================================================
6646 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6647 const SMESH::ListOfGroups& theNodesNot,
6648 GEOM::GEOM_Object_ptr theShape )
6649 throw (SALOME::SALOME_Exception)
6655 SMESHDS_Mesh* aMeshDS = getMeshDS();
6656 TIDSortedElemSet anElems, aNodes;
6657 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6658 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6660 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6661 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6663 // Update Python script
6664 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6665 << &theNodesNot << ", " << theShape << " )";
6667 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6670 SMESH_CATCH( SMESH::throwCorbaException );
6674 //================================================================================
6676 \brief Identify the elements that will be affected by node duplication (actual
6677 duplication is not performed.
6678 This method is the first step of DoubleNodeElemGroupsInRegion.
6679 \param theElems - list of groups of elements (edges or faces) to be replicated
6680 \param theNodesNot - list of groups of nodes not to replicated
6681 \param theShape - shape to detect affected elements (element which geometric center
6682 located on or inside shape).
6683 The replicated nodes should be associated to affected elements.
6684 \return groups of affected elements
6685 \sa DoubleNodeElemGroupsInRegion()
6687 //================================================================================
6688 SMESH::ListOfGroups*
6689 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6690 const SMESH::ListOfGroups& theNodesNot,
6691 GEOM::GEOM_Object_ptr theShape )
6692 throw (SALOME::SALOME_Exception)
6695 MESSAGE("AffectedElemGroupsInRegion");
6696 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6697 bool isEdgeGroup = false;
6698 bool isFaceGroup = false;
6699 bool isVolumeGroup = false;
6700 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6701 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6702 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6706 ::SMESH_MeshEditor aMeshEditor(myMesh);
6708 SMESHDS_Mesh* aMeshDS = getMeshDS();
6709 TIDSortedElemSet anElems, aNodes;
6710 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6711 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6713 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6714 TIDSortedElemSet anAffected;
6715 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6718 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6723 int lg = anAffected.size();
6724 MESSAGE("lg="<< lg);
6725 SMESH::long_array_var volumeIds = new SMESH::long_array;
6726 volumeIds->length(lg);
6727 SMESH::long_array_var faceIds = new SMESH::long_array;
6728 faceIds->length(lg);
6729 SMESH::long_array_var edgeIds = new SMESH::long_array;
6730 edgeIds->length(lg);
6735 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6736 for (; eIt != anAffected.end(); ++eIt)
6738 const SMDS_MeshElement* anElem = *eIt;
6741 int elemId = anElem->GetID();
6742 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6743 volumeIds[ivol++] = elemId;
6744 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6745 faceIds[iface++] = elemId;
6746 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6747 edgeIds[iedge++] = elemId;
6749 volumeIds->length(ivol);
6750 faceIds->length(iface);
6751 edgeIds->length(iedge);
6753 aNewVolumeGroup->Add(volumeIds);
6754 aNewFaceGroup->Add(faceIds);
6755 aNewEdgeGroup->Add(edgeIds);
6756 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6757 isFaceGroup = (aNewFaceGroup->Size() > 0);
6758 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6762 if (isEdgeGroup) nbGroups++;
6763 if (isFaceGroup) nbGroups++;
6764 if (isVolumeGroup) nbGroups++;
6765 aListOfGroups->length(nbGroups);
6768 if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
6769 if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
6770 if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
6772 // Update Python script
6775 if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
6776 if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
6777 if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
6779 pyDump << this << ".AffectedElemGroupsInRegion( "
6780 << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6782 return aListOfGroups._retn();
6784 SMESH_CATCH( SMESH::throwCorbaException );
6788 //================================================================================
6790 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6791 The created 2D mesh elements based on nodes of free faces of boundary volumes
6792 \return TRUE if operation has been completed successfully, FALSE otherwise
6794 //================================================================================
6796 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6797 throw (SALOME::SALOME_Exception)
6802 bool aResult = getEditor().Make2DMeshFrom3D();
6804 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6806 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6809 SMESH_CATCH( SMESH::throwCorbaException );
6813 //================================================================================
6815 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6816 * The list of groups must contain at least two groups. The groups have to be disjoint:
6817 * no common element into two different groups.
6818 * The nodes of the internal faces at the boundaries of the groups are doubled.
6819 * Optionally, the internal faces are replaced by flat elements.
6820 * Triangles are transformed into prisms, and quadrangles into hexahedrons.
6821 * The flat elements are stored in groups of volumes.
6822 * These groups are named according to the position of the group in the list:
6823 * 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.
6824 * 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.
6825 * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
6826 * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
6827 * @param theDomains - list of groups of volumes
6828 * @param createJointElems - if TRUE, create the elements
6829 * @return TRUE if operation has been completed successfully, FALSE otherwise
6831 //================================================================================
6834 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6835 CORBA::Boolean createJointElems )
6836 throw (SALOME::SALOME_Exception)
6838 bool aResult = false;
6843 SMESHDS_Mesh* aMeshDS = getMeshDS();
6845 // MESSAGE("theDomains.length = "<<theDomains.length());
6846 if ( theDomains.length() <= 1 )
6847 THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
6848 vector<TIDSortedElemSet> domains;
6851 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6853 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6854 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6856 // if ( aGrp->GetType() != SMESH::VOLUME )
6857 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6858 TIDSortedElemSet domain;
6860 domains.push_back(domain);
6861 SMESH::long_array_var anIDs = aGrp->GetIDs();
6862 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6866 aResult = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems );
6867 // TODO publish the groups of flat elements in study
6869 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6871 // Update Python script
6872 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6873 << ", " << createJointElems << " )";
6875 SMESH_CATCH( SMESH::throwCorbaException );
6880 //================================================================================
6882 * \brief Double nodes on some external faces and create flat elements.
6883 * Flat elements are mainly used by some types of mechanic calculations.
6885 * Each group of the list must be constituted of faces.
6886 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6887 * @param theGroupsOfFaces - list of groups of faces
6888 * @return TRUE if operation has been completed successfully, FALSE otherwise
6890 //================================================================================
6893 SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6894 throw (SALOME::SALOME_Exception)
6899 SMESHDS_Mesh* aMeshDS = getMeshDS();
6901 vector<TIDSortedElemSet> faceGroups;
6904 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6906 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6907 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6909 TIDSortedElemSet faceGroup;
6911 faceGroups.push_back(faceGroup);
6912 SMESH::long_array_var anIDs = aGrp->GetIDs();
6913 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6917 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
6918 // TODO publish the groups of flat elements in study
6920 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6922 // Update Python script
6923 TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6926 SMESH_CATCH( SMESH::throwCorbaException );
6930 //================================================================================
6932 * \brief Identify all the elements around a geom shape, get the faces delimiting
6935 * Build groups of volume to remove, groups of faces to replace on the skin of the
6936 * object, groups of faces to remove inside the object, (idem edges).
6937 * Build ordered list of nodes at the border of each group of faces to replace
6938 * (to be used to build a geom subshape).
6940 //================================================================================
6942 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6943 GEOM::GEOM_Object_ptr theShape,
6944 const char* groupName,
6945 const SMESH::double_array& theNodesCoords,
6946 SMESH::array_of_long_array_out GroupsOfNodes)
6947 throw (SALOME::SALOME_Exception)
6952 std::vector<std::vector<int> > aListOfListOfNodes;
6953 ::SMESH_MeshEditor aMeshEditor( myMesh );
6955 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
6956 if ( !theNodeSearcher )
6957 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
6959 vector<double> nodesCoords;
6960 for (int i = 0; i < theNodesCoords.length(); i++)
6962 nodesCoords.push_back( theNodesCoords[i] );
6965 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6966 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
6967 nodesCoords, aListOfListOfNodes);
6969 GroupsOfNodes = new SMESH::array_of_long_array;
6970 GroupsOfNodes->length( aListOfListOfNodes.size() );
6971 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
6972 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
6974 vector<int>& aListOfNodes = *llIt;
6975 vector<int>::iterator lIt = aListOfNodes.begin();;
6976 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
6977 aGroup.length( aListOfNodes.size() );
6978 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
6979 aGroup[ j ] = (*lIt);
6981 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
6984 << ", '" << groupName << "', "
6985 << theNodesCoords << " )";
6987 SMESH_CATCH( SMESH::throwCorbaException );
6990 // issue 20749 ===================================================================
6992 * \brief Creates missing boundary elements
6993 * \param elements - elements whose boundary is to be checked
6994 * \param dimension - defines type of boundary elements to create
6995 * \param groupName - a name of group to store created boundary elements in,
6996 * "" means not to create the group
6997 * \param meshName - a name of new mesh to store created boundary elements in,
6998 * "" means not to create the new mesh
6999 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
7000 * \param toCopyExistingBondary - if true, not only new but also pre-existing
7001 * boundary elements will be copied into the new mesh
7002 * \param group - returns the create group, if any
7003 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
7005 // ================================================================================
7007 SMESH::SMESH_Mesh_ptr
7008 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
7009 SMESH::Bnd_Dimension dim,
7010 const char* groupName,
7011 const char* meshName,
7012 CORBA::Boolean toCopyElements,
7013 CORBA::Boolean toCopyExistingBondary,
7014 SMESH::SMESH_Group_out group)
7015 throw (SALOME::SALOME_Exception)
7020 if ( dim > SMESH::BND_1DFROM2D )
7021 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7023 SMESHDS_Mesh* aMeshDS = getMeshDS();
7025 SMESH::SMESH_Mesh_var mesh_var;
7026 SMESH::SMESH_Group_var group_var;
7030 TIDSortedElemSet elements;
7031 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
7032 prepareIdSource( idSource );
7033 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
7037 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
7038 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7040 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
7042 // group of new boundary elements
7043 SMESH_Group* smesh_group = 0;
7044 if ( strlen(groupName) )
7046 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
7047 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7048 smesh_group = group_i->GetSmeshGroup();
7052 getEditor().MakeBoundaryMesh( elements,
7053 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7057 toCopyExistingBondary);
7060 smesh_mesh->GetMeshDS()->Modified();
7063 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7065 // result of MakeBoundaryMesh() is a tuple (mesh, group)
7066 if ( mesh_var->_is_nil() )
7067 pyDump << myMesh_i->_this() << ", ";
7069 pyDump << mesh_var << ", ";
7070 if ( group_var->_is_nil() )
7071 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7073 pyDump << group_var << " = ";
7074 pyDump << this << ".MakeBoundaryMesh( "
7076 << "SMESH." << dimName[int(dim)] << ", "
7077 << "'" << groupName << "', "
7078 << "'" << meshName<< "', "
7079 << toCopyElements << ", "
7080 << toCopyExistingBondary << ")";
7082 group = group_var._retn();
7083 return mesh_var._retn();
7085 SMESH_CATCH( SMESH::throwCorbaException );
7086 return SMESH::SMESH_Mesh::_nil();
7089 //================================================================================
7091 * \brief Creates missing boundary elements
7092 * \param dimension - defines type of boundary elements to create
7093 * \param groupName - a name of group to store all boundary elements in,
7094 * "" means not to create the group
7095 * \param meshName - a name of a new mesh, which is a copy of the initial
7096 * mesh + created boundary elements; "" means not to create the new mesh
7097 * \param toCopyAll - if true, the whole initial mesh will be copied into
7098 * the new mesh else only boundary elements will be copied into the new mesh
7099 * \param groups - optional groups of elements to make boundary around
7100 * \param mesh - returns the mesh where elements were added to
7101 * \param group - returns the created group, if any
7102 * \retval long - number of added boundary elements
7104 //================================================================================
7106 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
7107 const char* groupName,
7108 const char* meshName,
7109 CORBA::Boolean toCopyAll,
7110 const SMESH::ListOfIDSources& groups,
7111 SMESH::SMESH_Mesh_out mesh,
7112 SMESH::SMESH_Group_out group)
7113 throw (SALOME::SALOME_Exception)
7118 if ( dim > SMESH::BND_1DFROM2D )
7119 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7121 // separate groups belonging to this and other mesh
7122 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
7123 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
7124 groupsOfThisMesh->length( groups.length() );
7125 groupsOfOtherMesh->length( groups.length() );
7126 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
7127 for ( int i = 0; i < groups.length(); ++i )
7129 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
7130 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
7131 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
7133 groupsOfThisMesh[ nbGroups++ ] = groups[i];
7134 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
7135 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
7137 groupsOfThisMesh->length( nbGroups );
7138 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
7143 if ( nbGroupsOfOtherMesh > 0 )
7145 // process groups belonging to another mesh
7146 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
7147 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
7148 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
7149 groupsOfOtherMesh, mesh, group );
7152 SMESH::SMESH_Mesh_var mesh_var;
7153 SMESH::SMESH_Group_var group_var;
7156 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
7157 const bool toCopyMesh = ( strlen( meshName ) > 0 );
7161 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
7163 /*toCopyGroups=*/false,
7164 /*toKeepIDs=*/true);
7166 mesh_var = makeMesh(meshName);
7168 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7169 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
7172 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
7173 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
7175 // group of boundary elements
7176 SMESH_Group* smesh_group = 0;
7177 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
7178 if ( strlen(groupName) )
7180 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
7181 group_var = mesh_i->CreateGroup( groupType, groupName );
7182 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7183 smesh_group = group_i->GetSmeshGroup();
7186 TIDSortedElemSet elements;
7188 if ( groups.length() > 0 )
7190 for ( int i = 0; i < nbGroups; ++i )
7193 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
7195 SMESH::Bnd_Dimension bdim =
7196 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
7197 nbAdded += getEditor().MakeBoundaryMesh( elements,
7198 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
7201 /*toCopyElements=*/false,
7202 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7203 /*toAddExistingBondary=*/true,
7204 /*aroundElements=*/true);
7210 nbAdded += getEditor().MakeBoundaryMesh( elements,
7211 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7214 /*toCopyElements=*/false,
7215 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7216 /*toAddExistingBondary=*/true);
7218 tgtMesh->GetMeshDS()->Modified();
7220 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7222 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
7223 pyDump << "nbAdded, ";
7224 if ( mesh_var->_is_nil() )
7225 pyDump << myMesh_i->_this() << ", ";
7227 pyDump << mesh_var << ", ";
7228 if ( group_var->_is_nil() )
7229 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7231 pyDump << group_var << " = ";
7232 pyDump << this << ".MakeBoundaryElements( "
7233 << "SMESH." << dimName[int(dim)] << ", "
7234 << "'" << groupName << "', "
7235 << "'" << meshName<< "', "
7236 << toCopyAll << ", "
7239 mesh = mesh_var._retn();
7240 group = group_var._retn();
7243 SMESH_CATCH( SMESH::throwCorbaException );