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>
67 #include <BRepAdaptor_Surface.hxx>
68 #include <BRep_Tool.hxx>
69 #include <TopExp_Explorer.hxx>
71 #include <TopoDS_Edge.hxx>
72 #include <TopoDS_Face.hxx>
77 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
81 #include <Standard_Failure.hxx>
84 #include <Standard_ErrorHandler.hxx>
90 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
92 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
95 using SMESH::TPythonDump;
98 namespace MeshEditor_I {
100 //=============================================================================
102 * \brief Mesh to apply modifications for preview purposes
104 //=============================================================================
106 struct TPreviewMesh: public SMESH_Mesh
108 SMDSAbs_ElementType myPreviewType; // type to show
110 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
111 _isShapeToMesh = (_id =_studyId = 0);
112 _myMeshDS = new SMESHDS_Mesh( _id, true );
113 myPreviewType = previewElements;
116 virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
117 //!< Copy a set of elements
118 void Copy(const TIDSortedElemSet & theElements,
119 TIDSortedElemSet& theCopyElements,
120 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
121 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
123 // loop on theIDsOfElements
124 TIDSortedElemSet::const_iterator eIt = theElements.begin();
125 for ( ; eIt != theElements.end(); ++eIt )
127 const SMDS_MeshElement* anElem = *eIt;
128 if ( !anElem ) continue;
129 SMDSAbs_ElementType type = anElem->GetType();
130 if ( type == theAvoidType ||
131 ( theSelectType != SMDSAbs_All && type != theSelectType ))
133 const SMDS_MeshElement* anElemCopy;
134 if ( type == SMDSAbs_Node)
135 anElemCopy = Copy( cast2Node(anElem) );
137 anElemCopy = Copy( anElem );
139 theCopyElements.insert( theCopyElements.end(), anElemCopy );
143 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
145 // copy element nodes
146 int anElemNbNodes = anElem->NbNodes();
147 vector< int > anElemNodesID( anElemNbNodes ) ;
148 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
149 for ( int i = 0; itElemNodes->more(); i++)
151 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
153 anElemNodesID[i] = anElemNode->GetID();
156 // creates a corresponding element on copied nodes
157 SMDS_MeshElement* anElemCopy = 0;
158 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
160 const SMDS_VtkVolume* ph =
161 dynamic_cast<const SMDS_VtkVolume*> (anElem);
163 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
164 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
167 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
174 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
176 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
177 anElemNode->GetID());
179 };// struct TPreviewMesh
181 static SMESH_NodeSearcher * theNodeSearcher = 0;
182 static SMESH_ElementSearcher * theElementSearcher = 0;
184 //=============================================================================
186 * \brief Deleter of theNodeSearcher at any compute event occured
188 //=============================================================================
190 struct TSearchersDeleter : public SMESH_subMeshEventListener
193 string myMeshPartIOR;
195 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
196 "SMESH_MeshEditor_i::TSearchersDeleter"),
198 //!< Delete theNodeSearcher
201 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
202 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
204 typedef map < int, SMESH_subMesh * > TDependsOnMap;
205 //!< The meshod called by submesh: do my main job
206 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
207 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
209 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
211 Unset( sm->GetFather() );
214 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
215 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
217 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
224 myMeshPartIOR = meshPartIOR;
225 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
226 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
227 TDependsOnMap::const_iterator sm;
228 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
229 sm->second->SetEventListener( this, 0, sm->second );
233 //!< delete self from all submeshes
234 void Unset(SMESH_Mesh* mesh)
236 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
237 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
238 TDependsOnMap::const_iterator sm;
239 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
240 sm->second->DeleteEventListener( this );
245 } theSearchersDeleter;
247 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
249 TCollection_AsciiString typeStr;
250 switch ( theMirrorType ) {
251 case SMESH::SMESH_MeshEditor::POINT:
252 typeStr = "SMESH.SMESH_MeshEditor.POINT";
254 case SMESH::SMESH_MeshEditor::AXIS:
255 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
258 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
262 //================================================================================
264 * \brief function for conversion of long_array to TIDSortedElemSet
265 * \param IDs - array of IDs
266 * \param aMesh - mesh
267 * \param aMap - collection to fill
268 * \param aType - element type
270 //================================================================================
272 void arrayToSet(const SMESH::long_array & IDs,
273 const SMESHDS_Mesh* aMesh,
274 TIDSortedElemSet& aMap,
275 const SMDSAbs_ElementType aType = SMDSAbs_All )
277 SMDS_MeshElement::NonNullFilter filter1;
278 SMDS_MeshElement::TypeFilter filter2( aType );
279 SMDS_MeshElement::Filter & filter =
280 ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter&) filter1 : filter2;
282 if ( aType == SMDSAbs_Node )
283 for (int i=0; i<IDs.length(); i++) {
284 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
286 aMap.insert( aMap.end(), elem );
289 for (int i=0; i<IDs.length(); i++) {
290 const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
292 aMap.insert( aMap.end(), elem );
295 //================================================================================
297 * \brief Retrieve elements of given type from SMESH_IDSource
299 //================================================================================
301 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
302 const SMESHDS_Mesh* theMeshDS,
303 TIDSortedElemSet& theElemSet,
304 const SMDSAbs_ElementType theType,
305 const bool emptyIfIsMesh=false)
308 if ( CORBA::is_nil( theIDSource ) )
310 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
313 SMESH::long_array_var anIDs = theIDSource->GetIDs();
314 if ( anIDs->length() == 0 )
316 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
317 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
319 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
320 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
326 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
327 return bool(anIDs->length()) == bool(theElemSet.size());
331 //================================================================================
333 * \brief Retrieve nodes from SMESH_IDSource
335 //================================================================================
337 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
338 const SMESHDS_Mesh* theMeshDS,
339 TIDSortedNodeSet& theNodeSet)
342 if ( CORBA::is_nil( theObject ) )
344 SMESH::array_of_ElementType_var types = theObject->GetTypes();
345 SMESH::long_array_var aElementsId = theObject->GetIDs();
346 if ( types->length() == 1 && types[0] == SMESH::NODE)
348 for(int i = 0; i < aElementsId->length(); i++)
349 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
350 theNodeSet.insert( theNodeSet.end(), n);
352 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
354 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
355 while ( nIt->more( ))
356 if( const SMDS_MeshElement * elem = nIt->next() )
357 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
361 for(int i = 0; i < aElementsId->length(); i++)
362 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
363 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
367 //================================================================================
369 * \brief Returns elements connected to the given elements
371 //================================================================================
373 void getElementsAround(const TIDSortedElemSet& theElements,
374 const SMESHDS_Mesh* theMeshDS,
375 TIDSortedElemSet& theElementsAround)
377 if ( theElements.empty() ) return;
379 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
380 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
382 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
383 return; // all the elements are in theElements
386 elemType = SMDSAbs_All;
388 TIDSortedElemSet visitedNodes;
389 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
390 for ( ; elemIt != theElements.end(); ++elemIt )
392 const SMDS_MeshElement* e = *elemIt;
393 int i = e->NbCornerNodes();
396 const SMDS_MeshNode* n = e->GetNode( i );
397 if ( visitedNodes.insert( n ).second )
399 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
400 while ( invIt->more() )
402 const SMDS_MeshElement* elemAround = invIt->next();
403 if ( !theElements.count( elemAround ))
404 theElementsAround.insert( elemAround );
411 //================================================================================
413 * \brief Return a string used to detect change of mesh part on which theElementSearcher
414 * is going to be used
416 //================================================================================
418 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
420 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
421 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
422 // take into account passible group modification
423 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
424 partIOR += SMESH_Comment( type );
428 } // namespace MeshEditor_I
430 using namespace MeshEditor_I;
432 //=============================================================================
436 //=============================================================================
438 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
440 myMesh( &theMesh->GetImpl() ),
442 myIsPreviewMode ( isPreview ),
448 //================================================================================
452 //================================================================================
454 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
456 deleteAuxIDSources();
457 delete myPreviewMesh; myPreviewMesh = 0;
458 delete myPreviewEditor; myPreviewEditor = 0;
461 //================================================================================
463 * \brief Clear members
465 //================================================================================
467 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
469 if ( myIsPreviewMode ) {
470 if ( myPreviewMesh ) myPreviewMesh->Clear();
473 if ( deleteSearchers )
474 TSearchersDeleter::Delete();
476 getEditor().GetError().reset();
477 getEditor().CrearLastCreated();
480 //================================================================================
482 * \brief Increment mesh modif time and optionally record that the performed
483 * modification may influence futher mesh re-compute.
484 * \param [in] isReComputeSafe - true if the modification does not infulence
485 * futher mesh re-compute
487 //================================================================================
489 void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
491 myMesh->GetMeshDS()->Modified();
492 if ( !isReComputeSafe )
493 myMesh->SetIsModified( true );
496 //================================================================================
498 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
499 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
501 //================================================================================
503 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
505 if ( myIsPreviewMode && !myPreviewEditor ) {
506 if ( !myPreviewMesh ) getPreviewMesh();
507 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
509 return myIsPreviewMode ? *myPreviewEditor : myEditor;
512 //================================================================================
514 * \brief Initialize and return myPreviewMesh
515 * \param previewElements - type of elements to show in preview
517 * WARNING: call it once par a method!
519 //================================================================================
521 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
523 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
525 delete myPreviewEditor;
527 delete myPreviewMesh;
528 myPreviewMesh = new TPreviewMesh( previewElements );
530 myPreviewMesh->Clear();
531 return myPreviewMesh;
534 //================================================================================
536 * Return data of mesh edition preview
538 //================================================================================
540 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
541 throw (SALOME::SALOME_Exception)
544 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
546 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
548 list<int> aNodesConnectivity;
549 typedef map<int, int> TNodesMap;
552 SMESHDS_Mesh* aMeshDS;
553 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
555 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
556 aMeshDS = aMeshPartDS.get();
559 aMeshDS = getEditor().GetMeshDS();
561 myPreviewData = new SMESH::MeshPreviewStruct();
562 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
565 SMDSAbs_ElementType previewType = SMDSAbs_All;
567 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
568 previewType = aPreviewMesh->myPreviewType;
569 switch ( previewType ) {
570 case SMDSAbs_Edge : break;
571 case SMDSAbs_Face : break;
572 case SMDSAbs_Volume: break;
574 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
578 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
580 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
582 while ( itMeshElems->more() ) {
583 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
584 SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator();
585 while ( itElemNodes->more() ) {
586 const SMDS_MeshNode* aMeshNode = itElemNodes->next();
587 int aNodeID = aMeshNode->GetID();
588 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
589 if ( anIter == nodesMap.end() ) {
590 // filling the nodes coordinates
591 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
592 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
593 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
594 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
597 aNodesConnectivity.push_back(anIter->second);
600 // filling the elements types
601 SMDSAbs_ElementType aType = aMeshElem->GetType();
602 bool isPoly = aMeshElem->IsPoly();
603 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
604 myPreviewData->elementTypes[i].isPoly = isPoly;
605 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
608 myPreviewData->nodesXYZ.length( j );
610 // filling the elements connectivities
611 list<int>::iterator aConnIter = aNodesConnectivity.begin();
612 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
613 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
614 myPreviewData->elementConnectivities[i] = *aConnIter;
616 return myPreviewData._retn();
618 SMESH_CATCH( SMESH::throwCorbaException );
622 //================================================================================
624 * \brief Returns list of it's IDs of created nodes
625 * \retval SMESH::long_array* - list of node ID
627 //================================================================================
629 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
630 throw (SALOME::SALOME_Exception)
633 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
635 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
636 myLastCreatedNodes->length( aSeq.Length() );
637 for (int i = 1; i <= aSeq.Length(); i++)
638 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
640 return myLastCreatedNodes._retn();
641 SMESH_CATCH( SMESH::throwCorbaException );
645 //================================================================================
647 * \brief Returns list of it's IDs of created elements
648 * \retval SMESH::long_array* - list of elements' ID
650 //================================================================================
652 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
653 throw (SALOME::SALOME_Exception)
656 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
658 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
659 myLastCreatedElems->length( aSeq.Length() );
660 for ( int i = 1; i <= aSeq.Length(); i++ )
661 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
663 return myLastCreatedElems._retn();
664 SMESH_CATCH( SMESH::throwCorbaException );
668 //=======================================================================
669 //function : ClearLastCreated
670 //purpose : Clears sequences of last created elements and nodes
671 //=======================================================================
673 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
676 getEditor().CrearLastCreated();
677 SMESH_CATCH( SMESH::throwCorbaException );
680 //=======================================================================
682 * Returns description of an error/warning occured during the last operation
683 * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
685 //=======================================================================
687 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
688 throw (SALOME::SALOME_Exception)
691 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
692 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
693 if ( errIn && !errIn->IsOK() )
695 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
696 errOut->comment = errIn->myComment.c_str();
697 errOut->subShapeID = -1;
698 errOut->hasBadMesh = !errIn->myBadElements.empty();
703 errOut->subShapeID = -1;
704 errOut->hasBadMesh = false;
707 return errOut._retn();
708 SMESH_CATCH( SMESH::throwCorbaException );
712 //=======================================================================
713 //function : MakeIDSource
714 //purpose : Wrap a sequence of ids in a SMESH_IDSource
715 //=======================================================================
717 struct SMESH_MeshEditor_i::_IDSource : public POA_SMESH::SMESH_IDSource
719 SMESH::long_array _ids;
720 SMESH::ElementType _type;
721 SMESH::SMESH_Mesh_ptr _mesh;
722 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
723 SMESH::long_array* GetMeshInfo() { return 0; }
724 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
725 bool IsMeshInfoCorrect() { return true; }
726 SMESH::array_of_ElementType* GetTypes()
728 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
729 if ( _ids.length() > 0 ) {
733 return types._retn();
737 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
738 SMESH::ElementType type)
740 if ( myAuxIDSources.size() > 10 )
741 deleteAuxIDSources();
743 _IDSource* idSrc = new _IDSource;
744 idSrc->_mesh = myMesh_i->_this();
747 myAuxIDSources.push_back( idSrc );
749 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
751 return anIDSourceVar._retn();
754 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
756 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
759 void SMESH_MeshEditor_i::deleteAuxIDSources()
761 std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
762 for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
764 myAuxIDSources.clear();
767 //=============================================================================
771 //=============================================================================
774 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
775 throw (SALOME::SALOME_Exception)
782 for (int i = 0; i < IDsOfElements.length(); i++)
783 IdList.push_back( IDsOfElements[i] );
785 // Update Python script
786 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
789 bool ret = getEditor().Remove( IdList, false );
791 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
794 SMESH_CATCH( SMESH::throwCorbaException );
798 //=============================================================================
802 //=============================================================================
804 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
805 throw (SALOME::SALOME_Exception)
811 for (int i = 0; i < IDsOfNodes.length(); i++)
812 IdList.push_back( IDsOfNodes[i] );
814 // Update Python script
815 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
817 bool ret = getEditor().Remove( IdList, true );
819 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
822 SMESH_CATCH( SMESH::throwCorbaException );
826 //=============================================================================
830 //=============================================================================
832 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
833 throw (SALOME::SALOME_Exception)
838 // Update Python script
839 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
841 // Create filter to find all orphan nodes
842 SMESH::Controls::Filter::TIdSequence seq;
843 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
844 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
846 // remove orphan nodes (if there are any)
848 for ( int i = 0; i < seq.size(); i++ )
849 IdList.push_back( seq[i] );
851 int nbNodesBefore = myMesh->NbNodes();
852 getEditor().Remove( IdList, true );
853 int nbNodesAfter = myMesh->NbNodes();
855 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
856 return nbNodesBefore - nbNodesAfter;
858 SMESH_CATCH( SMESH::throwCorbaException );
862 //=============================================================================
866 //=============================================================================
868 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
869 throw (SALOME::SALOME_Exception)
874 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
876 // Update Python script
877 TPythonDump() << "nodeID = " << this << ".AddNode( "
878 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
880 declareMeshModified( /*isReComputeSafe=*/false );
883 SMESH_CATCH( SMESH::throwCorbaException );
887 //=============================================================================
889 * Create 0D element on the given node.
891 //=============================================================================
893 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
894 throw (SALOME::SALOME_Exception)
899 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
900 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
902 // Update Python script
903 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
905 declareMeshModified( /*isReComputeSafe=*/false );
907 return elem ? elem->GetID() : 0;
909 SMESH_CATCH( SMESH::throwCorbaException );
913 //=============================================================================
915 * Create a ball element on the given node.
917 //=============================================================================
919 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
920 throw (SALOME::SALOME_Exception)
925 if ( diameter < std::numeric_limits<double>::min() )
926 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
928 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
929 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
931 // Update Python script
932 TPythonDump() << "ballElem = "
933 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
935 declareMeshModified( /*isReComputeSafe=*/false );
936 return elem ? elem->GetID() : 0;
938 SMESH_CATCH( SMESH::throwCorbaException );
942 //=============================================================================
944 * Create an edge, either linear and quadratic (this is determed
945 * by number of given nodes, two or three)
947 //=============================================================================
949 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
950 throw (SALOME::SALOME_Exception)
955 int NbNodes = IDsOfNodes.length();
956 SMDS_MeshElement* elem = 0;
959 CORBA::Long index1 = IDsOfNodes[0];
960 CORBA::Long index2 = IDsOfNodes[1];
961 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
962 getMeshDS()->FindNode(index2));
964 // Update Python script
965 TPythonDump() << "edge = " << this << ".AddEdge([ "
966 << index1 << ", " << index2 <<" ])";
969 CORBA::Long n1 = IDsOfNodes[0];
970 CORBA::Long n2 = IDsOfNodes[1];
971 CORBA::Long n12 = IDsOfNodes[2];
972 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
973 getMeshDS()->FindNode(n2),
974 getMeshDS()->FindNode(n12));
975 // Update Python script
976 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
977 <<n1<<", "<<n2<<", "<<n12<<" ])";
980 declareMeshModified( /*isReComputeSafe=*/false );
981 return elem ? elem->GetID() : 0;
983 SMESH_CATCH( SMESH::throwCorbaException );
987 //=============================================================================
991 //=============================================================================
993 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
994 throw (SALOME::SALOME_Exception)
999 int NbNodes = IDsOfNodes.length();
1005 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1006 for (int i = 0; i < NbNodes; i++)
1007 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1009 SMDS_MeshElement* elem = 0;
1011 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1012 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1013 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1014 nodes[4], nodes[5]); break;
1015 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1016 nodes[4], nodes[5], nodes[6]); break;
1017 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1018 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1019 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1020 nodes[4], nodes[5], nodes[6], nodes[7],
1022 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1025 // Update Python script
1026 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1028 declareMeshModified( /*isReComputeSafe=*/false );
1030 return elem ? elem->GetID() : 0;
1032 SMESH_CATCH( SMESH::throwCorbaException );
1036 //=============================================================================
1040 //=============================================================================
1041 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1042 throw (SALOME::SALOME_Exception)
1047 int NbNodes = IDsOfNodes.length();
1048 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1049 for (int i = 0; i < NbNodes; i++)
1050 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1052 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1054 // Update Python script
1055 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1057 declareMeshModified( /*isReComputeSafe=*/false );
1058 return elem ? elem->GetID() : 0;
1060 SMESH_CATCH( SMESH::throwCorbaException );
1064 //=============================================================================
1066 * Create volume, either linear and quadratic (this is determed
1067 * by number of given nodes)
1069 //=============================================================================
1071 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1072 throw (SALOME::SALOME_Exception)
1077 int NbNodes = IDsOfNodes.length();
1078 vector< const SMDS_MeshNode*> n(NbNodes);
1079 for(int i=0;i<NbNodes;i++)
1080 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1082 SMDS_MeshElement* elem = 0;
1085 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1086 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1087 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1088 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1089 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1090 n[6],n[7],n[8],n[9]);
1092 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1093 n[6],n[7],n[8],n[9],n[10],n[11]);
1095 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1096 n[7],n[8],n[9],n[10],n[11],n[12]);
1098 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1099 n[9],n[10],n[11],n[12],n[13],n[14]);
1101 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1102 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1103 n[15],n[16],n[17],n[18],n[19]);
1105 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1106 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1107 n[15],n[16],n[17],n[18],n[19],
1108 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1112 // Update Python script
1113 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1115 declareMeshModified( /*isReComputeSafe=*/false );
1116 return elem ? elem->GetID() : 0;
1118 SMESH_CATCH( SMESH::throwCorbaException );
1122 //=============================================================================
1124 * AddPolyhedralVolume
1126 //=============================================================================
1127 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1128 const SMESH::long_array & Quantities)
1129 throw (SALOME::SALOME_Exception)
1134 int NbNodes = IDsOfNodes.length();
1135 std::vector<const SMDS_MeshNode*> n (NbNodes);
1136 for (int i = 0; i < NbNodes; i++)
1138 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1139 if (!aNode) return 0;
1143 int NbFaces = Quantities.length();
1144 std::vector<int> q (NbFaces);
1145 for (int j = 0; j < NbFaces; j++)
1146 q[j] = Quantities[j];
1148 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1150 // Update Python script
1151 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1152 << IDsOfNodes << ", " << Quantities << " )";
1154 declareMeshModified( /*isReComputeSafe=*/false );
1155 return elem ? elem->GetID() : 0;
1157 SMESH_CATCH( SMESH::throwCorbaException );
1161 //=============================================================================
1163 * AddPolyhedralVolumeByFaces
1165 //=============================================================================
1167 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1168 throw (SALOME::SALOME_Exception)
1173 int NbFaces = IdsOfFaces.length();
1174 std::vector<const SMDS_MeshNode*> poly_nodes;
1175 std::vector<int> quantities (NbFaces);
1177 for (int i = 0; i < NbFaces; i++) {
1178 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1179 quantities[i] = aFace->NbNodes();
1181 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1182 while (It->more()) {
1183 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1187 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1189 // Update Python script
1190 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1191 << IdsOfFaces << " )";
1193 declareMeshModified( /*isReComputeSafe=*/false );
1194 return elem ? elem->GetID() : 0;
1196 SMESH_CATCH( SMESH::throwCorbaException );
1200 //=============================================================================
1202 // \brief Create 0D elements on all nodes of the given object except those
1203 // nodes on which a 0D element already exists.
1204 // \param theObject object on whose nodes 0D elements will be created.
1205 // \param theGroupName optional name of a group to add 0D elements created
1206 // and/or found on nodes of \a theObject.
1207 // \return an object (a new group or a temporary SMESH_IDSource) holding
1208 // ids of new and/or found 0D elements.
1210 //=============================================================================
1212 SMESH::SMESH_IDSource_ptr
1213 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1214 const char* theGroupName)
1215 throw (SALOME::SALOME_Exception)
1220 SMESH::SMESH_IDSource_var result;
1223 TIDSortedElemSet elements, elems0D;
1224 prepareIdSource( theObject );
1225 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1226 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1228 SMESH::long_array_var newElems = new SMESH::long_array;
1229 newElems->length( elems0D.size() );
1230 TIDSortedElemSet::iterator eIt = elems0D.begin();
1231 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1232 newElems[ i ] = (*eIt)->GetID();
1234 SMESH::SMESH_GroupBase_var groupToFill;
1235 if ( theGroupName && strlen( theGroupName ))
1237 // Get existing group named theGroupName
1238 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1239 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1240 SMESH::SMESH_GroupBase_var group = groups[i];
1241 if ( !group->_is_nil() ) {
1242 CORBA::String_var name = group->GetName();
1243 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1244 groupToFill = group;
1249 if ( groupToFill->_is_nil() )
1250 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1251 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1252 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1255 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1257 group_i->Add( newElems );
1258 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1259 pyDump << groupToFill;
1263 result = MakeIDSource( newElems, SMESH::ELEM0D );
1264 pyDump << "elem0DIDs";
1267 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1268 << theObject << ", '" << theGroupName << "' )";
1270 return result._retn();
1272 SMESH_CATCH( SMESH::throwCorbaException );
1276 //=============================================================================
1278 * \brief Bind a node to a vertex
1279 * \param NodeID - node ID
1280 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1281 * \retval boolean - false if NodeID or VertexID is invalid
1283 //=============================================================================
1285 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1286 throw (SALOME::SALOME_Exception)
1290 SMESHDS_Mesh * mesh = getMeshDS();
1291 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1293 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1295 if ( mesh->MaxShapeIndex() < VertexID )
1296 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1298 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1299 if ( shape.ShapeType() != TopAbs_VERTEX )
1300 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1302 mesh->SetNodeOnVertex( node, VertexID );
1304 myMesh->SetIsModified( true );
1306 SMESH_CATCH( SMESH::throwCorbaException );
1309 //=============================================================================
1311 * \brief Store node position on an edge
1312 * \param NodeID - node ID
1313 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1314 * \param paramOnEdge - parameter on edge where the node is located
1315 * \retval boolean - false if any parameter is invalid
1317 //=============================================================================
1319 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1320 CORBA::Double paramOnEdge)
1321 throw (SALOME::SALOME_Exception)
1325 SMESHDS_Mesh * mesh = getMeshDS();
1326 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1328 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1330 if ( mesh->MaxShapeIndex() < EdgeID )
1331 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1333 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1334 if ( shape.ShapeType() != TopAbs_EDGE )
1335 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1338 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1339 if ( paramOnEdge < f || paramOnEdge > l )
1340 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1342 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1344 myMesh->SetIsModified( true );
1346 SMESH_CATCH( SMESH::throwCorbaException );
1349 //=============================================================================
1351 * \brief Store node position on a face
1352 * \param NodeID - node ID
1353 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1354 * \param u - U parameter on face where the node is located
1355 * \param v - V parameter on face where the node is located
1356 * \retval boolean - false if any parameter is invalid
1358 //=============================================================================
1360 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1361 CORBA::Double u, CORBA::Double v)
1362 throw (SALOME::SALOME_Exception)
1365 SMESHDS_Mesh * mesh = getMeshDS();
1366 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1368 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1370 if ( mesh->MaxShapeIndex() < FaceID )
1371 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1373 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1374 if ( shape.ShapeType() != TopAbs_FACE )
1375 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1377 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1378 bool isOut = ( u < surf.FirstUParameter() ||
1379 u > surf.LastUParameter() ||
1380 v < surf.FirstVParameter() ||
1381 v > surf.LastVParameter() );
1385 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1386 << " u( " << surf.FirstUParameter()
1387 << "," << surf.LastUParameter()
1388 << ") v( " << surf.FirstVParameter()
1389 << "," << surf.LastVParameter() << ")" );
1391 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1394 mesh->SetNodeOnFace( node, FaceID, u, v );
1395 myMesh->SetIsModified( true );
1397 SMESH_CATCH( SMESH::throwCorbaException );
1400 //=============================================================================
1402 * \brief Bind a node to a solid
1403 * \param NodeID - node ID
1404 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1405 * \retval boolean - false if NodeID or SolidID is invalid
1407 //=============================================================================
1409 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1410 throw (SALOME::SALOME_Exception)
1413 SMESHDS_Mesh * mesh = getMeshDS();
1414 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1416 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1418 if ( mesh->MaxShapeIndex() < SolidID )
1419 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1421 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1422 if ( shape.ShapeType() != TopAbs_SOLID &&
1423 shape.ShapeType() != TopAbs_SHELL)
1424 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1426 mesh->SetNodeInVolume( node, SolidID );
1428 SMESH_CATCH( SMESH::throwCorbaException );
1431 //=============================================================================
1433 * \brief Bind an element to a shape
1434 * \param ElementID - element ID
1435 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1437 //=============================================================================
1439 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1440 CORBA::Long ShapeID)
1441 throw (SALOME::SALOME_Exception)
1444 SMESHDS_Mesh * mesh = getMeshDS();
1445 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1447 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1449 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1450 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1452 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1453 if ( shape.ShapeType() != TopAbs_EDGE &&
1454 shape.ShapeType() != TopAbs_FACE &&
1455 shape.ShapeType() != TopAbs_SOLID &&
1456 shape.ShapeType() != TopAbs_SHELL )
1457 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1459 mesh->SetMeshElementOnShape( elem, ShapeID );
1461 myMesh->SetIsModified( true );
1463 SMESH_CATCH( SMESH::throwCorbaException );
1466 //=============================================================================
1470 //=============================================================================
1472 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1473 CORBA::Long NodeID2)
1474 throw (SALOME::SALOME_Exception)
1479 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1480 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1484 // Update Python script
1485 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1486 << NodeID1 << ", " << NodeID2 << " )";
1488 int ret = getEditor().InverseDiag ( n1, n2 );
1490 declareMeshModified( /*isReComputeSafe=*/false );
1493 SMESH_CATCH( SMESH::throwCorbaException );
1497 //=============================================================================
1501 //=============================================================================
1503 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1504 CORBA::Long NodeID2)
1505 throw (SALOME::SALOME_Exception)
1510 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1511 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1515 // Update Python script
1516 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1517 << NodeID1 << ", " << NodeID2 << " )";
1520 bool stat = getEditor().DeleteDiag ( n1, n2 );
1522 declareMeshModified( /*isReComputeSafe=*/!stat );
1526 SMESH_CATCH( SMESH::throwCorbaException );
1530 //=============================================================================
1534 //=============================================================================
1536 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1537 throw (SALOME::SALOME_Exception)
1542 for (int i = 0; i < IDsOfElements.length(); i++)
1544 CORBA::Long index = IDsOfElements[i];
1545 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1547 getEditor().Reorient( elem );
1549 // Update Python script
1550 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1552 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1555 SMESH_CATCH( SMESH::throwCorbaException );
1559 //=============================================================================
1563 //=============================================================================
1565 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1566 throw (SALOME::SALOME_Exception)
1571 TPythonDump aTPythonDump; // suppress dump in Reorient()
1573 prepareIdSource( theObject );
1575 SMESH::long_array_var anElementsId = theObject->GetIDs();
1576 CORBA::Boolean isDone = Reorient(anElementsId);
1578 // Update Python script
1579 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1581 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1584 SMESH_CATCH( SMESH::throwCorbaException );
1588 //=======================================================================
1589 //function : Reorient2D
1590 //purpose : Reorient faces contained in \a the2Dgroup.
1591 // the2Dgroup - the mesh or its part to reorient
1592 // theDirection - desired direction of normal of \a theFace
1593 // theFace - ID of face whose orientation is checked.
1594 // It can be < 1 then \a thePoint is used to find a face.
1595 // thePoint - is used to find a face if \a theFace < 1.
1596 // return number of reoriented elements.
1597 //=======================================================================
1599 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1600 const SMESH::DirStruct& theDirection,
1601 CORBA::Long theFace,
1602 const SMESH::PointStruct& thePoint)
1603 throw (SALOME::SALOME_Exception)
1606 initData(/*deleteSearchers=*/false);
1608 TIDSortedElemSet elements;
1609 prepareIdSource( the2Dgroup );
1610 if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
1611 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1614 const SMDS_MeshElement* face = 0;
1617 face = getMeshDS()->FindElement( theFace );
1619 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1620 if ( face->GetType() != SMDSAbs_Face )
1621 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1625 // create theElementSearcher if needed
1626 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1627 if ( !theElementSearcher )
1629 if ( elements.empty() ) // search in the whole mesh
1631 if ( myMesh->NbFaces() == 0 )
1632 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1634 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1638 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1639 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1641 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1645 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1646 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1649 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1650 if ( !elements.empty() && !elements.count( face ))
1651 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1654 const SMESH::PointStruct * P = &theDirection.PS;
1655 gp_Vec dirVec( P->x, P->y, P->z );
1656 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1657 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1659 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1662 declareMeshModified( /*isReComputeSafe=*/false );
1664 TPythonDump() << this << ".Reorient2D( "
1665 << the2Dgroup << ", "
1666 << theDirection << ", "
1668 << thePoint << " )";
1672 SMESH_CATCH( SMESH::throwCorbaException );
1676 //=============================================================================
1678 * \brief Fuse neighbour triangles into quadrangles.
1680 //=============================================================================
1682 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1683 SMESH::NumericalFunctor_ptr Criterion,
1684 CORBA::Double MaxAngle)
1685 throw (SALOME::SALOME_Exception)
1690 SMESHDS_Mesh* aMesh = getMeshDS();
1691 TIDSortedElemSet faces;
1692 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1694 SMESH::NumericalFunctor_i* aNumericalFunctor =
1695 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1696 SMESH::Controls::NumericalFunctorPtr aCrit;
1697 if ( !aNumericalFunctor )
1698 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1700 aCrit = aNumericalFunctor->GetNumericalFunctor();
1702 // Update Python script
1703 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1704 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1707 bool stat = getEditor().TriToQuad( faces, aCrit, MaxAngle );
1709 declareMeshModified( /*isReComputeSafe=*/!stat );
1712 SMESH_CATCH( SMESH::throwCorbaException );
1716 //=============================================================================
1718 * \brief Fuse neighbour triangles into quadrangles.
1720 //=============================================================================
1722 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1723 SMESH::NumericalFunctor_ptr Criterion,
1724 CORBA::Double MaxAngle)
1725 throw (SALOME::SALOME_Exception)
1730 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1732 prepareIdSource( theObject );
1733 SMESH::long_array_var anElementsId = theObject->GetIDs();
1734 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1736 SMESH::NumericalFunctor_i* aNumericalFunctor =
1737 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1739 // Update Python script
1740 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1741 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1745 SMESH_CATCH( SMESH::throwCorbaException );
1749 //=============================================================================
1751 * \brief Split quadrangles into triangles.
1753 //=============================================================================
1755 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1756 SMESH::NumericalFunctor_ptr Criterion)
1757 throw (SALOME::SALOME_Exception)
1762 SMESHDS_Mesh* aMesh = getMeshDS();
1763 TIDSortedElemSet faces;
1764 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1766 SMESH::NumericalFunctor_i* aNumericalFunctor =
1767 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1768 SMESH::Controls::NumericalFunctorPtr aCrit;
1769 if ( !aNumericalFunctor )
1770 aCrit.reset( new SMESH::Controls::AspectRatio() );
1772 aCrit = aNumericalFunctor->GetNumericalFunctor();
1775 // Update Python script
1776 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1778 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1780 declareMeshModified( /*isReComputeSafe=*/false );
1783 SMESH_CATCH( SMESH::throwCorbaException );
1787 //=============================================================================
1789 * \brief Split quadrangles into triangles.
1791 //=============================================================================
1793 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1794 SMESH::NumericalFunctor_ptr Criterion)
1795 throw (SALOME::SALOME_Exception)
1800 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1802 prepareIdSource( theObject );
1803 SMESH::long_array_var anElementsId = theObject->GetIDs();
1804 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1806 SMESH::NumericalFunctor_i* aNumericalFunctor =
1807 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1809 // Update Python script
1810 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1812 declareMeshModified( /*isReComputeSafe=*/false );
1815 SMESH_CATCH( SMESH::throwCorbaException );
1819 //================================================================================
1821 * \brief Split each of quadrangles into 4 triangles.
1822 * \param [in] theObject - theQuads Container of quadrangles to split.
1824 //================================================================================
1826 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1827 throw (SALOME::SALOME_Exception)
1832 TIDSortedElemSet faces;
1833 prepareIdSource( theObject );
1834 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1836 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1838 getEditor().QuadTo4Tri( faces );
1839 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1841 SMESH_CATCH( SMESH::throwCorbaException );
1844 //=============================================================================
1846 * \brief Split quadrangles into triangles.
1848 //=============================================================================
1850 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1851 CORBA::Boolean Diag13)
1852 throw (SALOME::SALOME_Exception)
1857 SMESHDS_Mesh* aMesh = getMeshDS();
1858 TIDSortedElemSet faces;
1859 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1861 // Update Python script
1862 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1863 << IDsOfElements << ", " << Diag13 << " )";
1865 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1867 declareMeshModified( /*isReComputeSafe=*/ !stat );
1870 SMESH_CATCH( SMESH::throwCorbaException );
1874 //=============================================================================
1876 * \brief Split quadrangles into triangles.
1878 //=============================================================================
1880 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1881 CORBA::Boolean Diag13)
1882 throw (SALOME::SALOME_Exception)
1887 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1889 prepareIdSource( theObject );
1890 SMESH::long_array_var anElementsId = theObject->GetIDs();
1891 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1893 // Update Python script
1894 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1895 << theObject << ", " << Diag13 << " )";
1897 declareMeshModified( /*isReComputeSafe=*/!isDone );
1900 SMESH_CATCH( SMESH::throwCorbaException );
1905 //=============================================================================
1907 * Find better splitting of the given quadrangle.
1908 * \param IDOfQuad ID of the quadrangle to be splitted.
1909 * \param Criterion A criterion to choose a diagonal for splitting.
1910 * \return 1 if 1-3 diagonal is better, 2 if 2-4
1911 * diagonal is better, 0 if error occurs.
1913 //=============================================================================
1915 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1916 SMESH::NumericalFunctor_ptr Criterion)
1917 throw (SALOME::SALOME_Exception)
1922 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
1923 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1925 SMESH::NumericalFunctor_i* aNumericalFunctor =
1926 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1927 SMESH::Controls::NumericalFunctorPtr aCrit;
1928 if (aNumericalFunctor)
1929 aCrit = aNumericalFunctor->GetNumericalFunctor();
1931 aCrit.reset(new SMESH::Controls::AspectRatio());
1933 int id = getEditor().BestSplit(quad, aCrit);
1934 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
1937 SMESH_CATCH( SMESH::throwCorbaException );
1941 //================================================================================
1943 * \brief Split volumic elements into tetrahedrons
1945 //================================================================================
1947 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1948 CORBA::Short methodFlags)
1949 throw (SALOME::SALOME_Exception)
1954 prepareIdSource( elems );
1955 SMESH::long_array_var anElementsId = elems->GetIDs();
1956 TIDSortedElemSet elemSet;
1957 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume );
1959 getEditor().SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1960 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
1962 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1963 << elems << ", " << methodFlags << " )";
1965 SMESH_CATCH( SMESH::throwCorbaException );
1968 //=======================================================================
1971 //=======================================================================
1974 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
1975 const SMESH::long_array & IDsOfFixedNodes,
1976 CORBA::Long MaxNbOfIterations,
1977 CORBA::Double MaxAspectRatio,
1978 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1979 throw (SALOME::SALOME_Exception)
1981 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1982 MaxAspectRatio, Method, false );
1986 //=======================================================================
1987 //function : SmoothParametric
1989 //=======================================================================
1992 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
1993 const SMESH::long_array & IDsOfFixedNodes,
1994 CORBA::Long MaxNbOfIterations,
1995 CORBA::Double MaxAspectRatio,
1996 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1997 throw (SALOME::SALOME_Exception)
1999 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2000 MaxAspectRatio, Method, true );
2004 //=======================================================================
2005 //function : SmoothObject
2007 //=======================================================================
2010 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2011 const SMESH::long_array & IDsOfFixedNodes,
2012 CORBA::Long MaxNbOfIterations,
2013 CORBA::Double MaxAspectRatio,
2014 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2015 throw (SALOME::SALOME_Exception)
2017 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2018 MaxAspectRatio, Method, false);
2022 //=======================================================================
2023 //function : SmoothParametricObject
2025 //=======================================================================
2028 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2029 const SMESH::long_array & IDsOfFixedNodes,
2030 CORBA::Long MaxNbOfIterations,
2031 CORBA::Double MaxAspectRatio,
2032 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2033 throw (SALOME::SALOME_Exception)
2035 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2036 MaxAspectRatio, Method, true);
2040 //=============================================================================
2044 //=============================================================================
2047 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2048 const SMESH::long_array & IDsOfFixedNodes,
2049 CORBA::Long MaxNbOfIterations,
2050 CORBA::Double MaxAspectRatio,
2051 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2053 throw (SALOME::SALOME_Exception)
2058 SMESHDS_Mesh* aMesh = getMeshDS();
2060 TIDSortedElemSet elements;
2061 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2063 set<const SMDS_MeshNode*> fixedNodes;
2064 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
2065 CORBA::Long index = IDsOfFixedNodes[i];
2066 const SMDS_MeshNode * node = aMesh->FindNode(index);
2068 fixedNodes.insert( node );
2070 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2071 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2072 method = ::SMESH_MeshEditor::CENTROIDAL;
2074 getEditor().Smooth(elements, fixedNodes, method,
2075 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2077 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2079 // Update Python script
2080 TPythonDump() << "isDone = " << this << "."
2081 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2082 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2083 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2084 << "SMESH.SMESH_MeshEditor."
2085 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2086 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2090 SMESH_CATCH( SMESH::throwCorbaException );
2094 //=============================================================================
2098 //=============================================================================
2101 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2102 const SMESH::long_array & IDsOfFixedNodes,
2103 CORBA::Long MaxNbOfIterations,
2104 CORBA::Double MaxAspectRatio,
2105 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2107 throw (SALOME::SALOME_Exception)
2112 TPythonDump aTPythonDump; // suppress dump in smooth()
2114 prepareIdSource( theObject );
2115 SMESH::long_array_var anElementsId = theObject->GetIDs();
2116 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2117 MaxAspectRatio, Method, IsParametric);
2119 // Update Python script
2120 aTPythonDump << "isDone = " << this << "."
2121 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2122 << theObject << ", " << IDsOfFixedNodes << ", "
2123 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2124 << "SMESH.SMESH_MeshEditor."
2125 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2126 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2130 SMESH_CATCH( SMESH::throwCorbaException );
2134 //=============================================================================
2138 //=============================================================================
2140 void SMESH_MeshEditor_i::RenumberNodes()
2141 throw (SALOME::SALOME_Exception)
2144 // Update Python script
2145 TPythonDump() << this << ".RenumberNodes()";
2147 getMeshDS()->Renumber( true );
2149 SMESH_CATCH( SMESH::throwCorbaException );
2152 //=============================================================================
2156 //=============================================================================
2158 void SMESH_MeshEditor_i::RenumberElements()
2159 throw (SALOME::SALOME_Exception)
2162 // Update Python script
2163 TPythonDump() << this << ".RenumberElements()";
2165 getMeshDS()->Renumber( false );
2167 SMESH_CATCH( SMESH::throwCorbaException );
2170 //=======================================================================
2172 * \brief Return groups by their IDs
2174 //=======================================================================
2176 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2177 throw (SALOME::SALOME_Exception)
2182 myMesh_i->CreateGroupServants();
2183 return myMesh_i->GetGroups( *groupIDs );
2185 SMESH_CATCH( SMESH::throwCorbaException );
2189 //=======================================================================
2190 //function : rotationSweep
2192 //=======================================================================
2194 SMESH::ListOfGroups*
2195 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2196 const SMESH::AxisStruct & theAxis,
2197 CORBA::Double theAngleInRadians,
2198 CORBA::Long theNbOfSteps,
2199 CORBA::Double theTolerance,
2200 const bool theMakeGroups,
2201 const SMDSAbs_ElementType theElementType)
2202 throw (SALOME::SALOME_Exception)
2207 TIDSortedElemSet inElements, copyElements;
2208 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2210 TIDSortedElemSet* workElements = & inElements;
2211 bool makeWalls=true;
2212 if ( myIsPreviewMode )
2214 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2215 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2216 workElements = & copyElements;
2217 //makeWalls = false;
2220 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2221 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2223 ::SMESH_MeshEditor::PGroupIDs groupIds =
2224 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2225 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2227 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2229 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2231 SMESH_CATCH( SMESH::throwCorbaException );
2235 //=======================================================================
2236 //function : RotationSweep
2238 //=======================================================================
2240 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2241 const SMESH::AxisStruct & theAxis,
2242 CORBA::Double theAngleInRadians,
2243 CORBA::Long theNbOfSteps,
2244 CORBA::Double theTolerance)
2245 throw (SALOME::SALOME_Exception)
2247 if ( !myIsPreviewMode ) {
2248 TPythonDump() << this << ".RotationSweep( "
2249 << theIDsOfElements << ", "
2251 << TVar( theAngleInRadians ) << ", "
2252 << TVar( theNbOfSteps ) << ", "
2253 << TVar( theTolerance ) << " )";
2255 rotationSweep(theIDsOfElements,
2263 //=======================================================================
2264 //function : RotationSweepMakeGroups
2266 //=======================================================================
2268 SMESH::ListOfGroups*
2269 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2270 const SMESH::AxisStruct& theAxis,
2271 CORBA::Double theAngleInRadians,
2272 CORBA::Long theNbOfSteps,
2273 CORBA::Double theTolerance)
2274 throw (SALOME::SALOME_Exception)
2276 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2278 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2284 if (!myIsPreviewMode) {
2285 dumpGroupsList(aPythonDump, aGroups);
2286 aPythonDump << this << ".RotationSweepMakeGroups( "
2287 << theIDsOfElements << ", "
2289 << TVar( theAngleInRadians ) << ", "
2290 << TVar( theNbOfSteps ) << ", "
2291 << TVar( theTolerance ) << " )";
2296 //=======================================================================
2297 //function : RotationSweepObject
2299 //=======================================================================
2301 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2302 const SMESH::AxisStruct & theAxis,
2303 CORBA::Double theAngleInRadians,
2304 CORBA::Long theNbOfSteps,
2305 CORBA::Double theTolerance)
2306 throw (SALOME::SALOME_Exception)
2308 if ( !myIsPreviewMode ) {
2309 TPythonDump() << this << ".RotationSweepObject( "
2310 << theObject << ", "
2312 << theAngleInRadians << ", "
2313 << theNbOfSteps << ", "
2314 << theTolerance << " )";
2316 prepareIdSource( theObject );
2317 SMESH::long_array_var anElementsId = theObject->GetIDs();
2318 rotationSweep(anElementsId,
2326 //=======================================================================
2327 //function : RotationSweepObject1D
2329 //=======================================================================
2331 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2332 const SMESH::AxisStruct & theAxis,
2333 CORBA::Double theAngleInRadians,
2334 CORBA::Long theNbOfSteps,
2335 CORBA::Double theTolerance)
2336 throw (SALOME::SALOME_Exception)
2338 if ( !myIsPreviewMode ) {
2339 TPythonDump() << this << ".RotationSweepObject1D( "
2340 << theObject << ", "
2342 << TVar( theAngleInRadians ) << ", "
2343 << TVar( theNbOfSteps ) << ", "
2344 << TVar( theTolerance ) << " )";
2346 prepareIdSource( theObject );
2347 SMESH::long_array_var anElementsId = theObject->GetIDs();
2348 rotationSweep(anElementsId,
2357 //=======================================================================
2358 //function : RotationSweepObject2D
2360 //=======================================================================
2362 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2363 const SMESH::AxisStruct & theAxis,
2364 CORBA::Double theAngleInRadians,
2365 CORBA::Long theNbOfSteps,
2366 CORBA::Double theTolerance)
2367 throw (SALOME::SALOME_Exception)
2369 if ( !myIsPreviewMode ) {
2370 TPythonDump() << this << ".RotationSweepObject2D( "
2371 << theObject << ", "
2373 << TVar( theAngleInRadians ) << ", "
2374 << TVar( theNbOfSteps ) << ", "
2375 << TVar( theTolerance ) << " )";
2377 prepareIdSource( theObject );
2378 SMESH::long_array_var anElementsId = theObject->GetIDs();
2379 rotationSweep(anElementsId,
2388 //=======================================================================
2389 //function : RotationSweepObjectMakeGroups
2391 //=======================================================================
2393 SMESH::ListOfGroups*
2394 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2395 const SMESH::AxisStruct& theAxis,
2396 CORBA::Double theAngleInRadians,
2397 CORBA::Long theNbOfSteps,
2398 CORBA::Double theTolerance)
2399 throw (SALOME::SALOME_Exception)
2401 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2403 prepareIdSource( theObject );
2404 SMESH::long_array_var anElementsId = theObject->GetIDs();
2405 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2411 if (!myIsPreviewMode) {
2412 dumpGroupsList(aPythonDump, aGroups);
2413 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2414 << theObject << ", "
2416 << theAngleInRadians << ", "
2417 << theNbOfSteps << ", "
2418 << theTolerance << " )";
2423 //=======================================================================
2424 //function : RotationSweepObject1DMakeGroups
2426 //=======================================================================
2428 SMESH::ListOfGroups*
2429 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2430 const SMESH::AxisStruct& theAxis,
2431 CORBA::Double theAngleInRadians,
2432 CORBA::Long theNbOfSteps,
2433 CORBA::Double theTolerance)
2434 throw (SALOME::SALOME_Exception)
2436 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2438 prepareIdSource( theObject );
2439 SMESH::long_array_var anElementsId = theObject->GetIDs();
2440 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2447 if (!myIsPreviewMode) {
2448 dumpGroupsList(aPythonDump, aGroups);
2449 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2450 << theObject << ", "
2452 << TVar( theAngleInRadians ) << ", "
2453 << TVar( theNbOfSteps ) << ", "
2454 << TVar( theTolerance ) << " )";
2459 //=======================================================================
2460 //function : RotationSweepObject2DMakeGroups
2462 //=======================================================================
2464 SMESH::ListOfGroups*
2465 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2466 const SMESH::AxisStruct& theAxis,
2467 CORBA::Double theAngleInRadians,
2468 CORBA::Long theNbOfSteps,
2469 CORBA::Double theTolerance)
2470 throw (SALOME::SALOME_Exception)
2472 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2474 prepareIdSource( theObject );
2475 SMESH::long_array_var anElementsId = theObject->GetIDs();
2476 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2483 if (!myIsPreviewMode) {
2484 dumpGroupsList(aPythonDump, aGroups);
2485 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2486 << theObject << ", "
2488 << TVar( theAngleInRadians ) << ", "
2489 << TVar( theNbOfSteps ) << ", "
2490 << TVar( theTolerance ) << " )";
2496 //=======================================================================
2497 //function : extrusionSweep
2499 //=======================================================================
2501 SMESH::ListOfGroups*
2502 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2503 const SMESH::DirStruct & theStepVector,
2504 CORBA::Long theNbOfSteps,
2506 const SMDSAbs_ElementType theElementType)
2507 throw (SALOME::SALOME_Exception)
2512 TIDSortedElemSet elements, copyElements;
2513 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2515 const SMESH::PointStruct * P = &theStepVector.PS;
2516 gp_Vec stepVec( P->x, P->y, P->z );
2518 TIDSortedElemSet* workElements = & elements;
2520 SMDSAbs_ElementType aType = SMDSAbs_Face;
2521 if (theElementType == SMDSAbs_Node)
2523 aType = SMDSAbs_Edge;
2525 if ( myIsPreviewMode ) {
2526 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2527 getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
2528 workElements = & copyElements;
2529 theMakeGroups = false;
2532 TElemOfElemListMap aHystory;
2533 ::SMESH_MeshEditor::PGroupIDs groupIds =
2534 getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2536 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2538 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2540 SMESH_CATCH( SMESH::throwCorbaException );
2544 //=======================================================================
2545 //function : ExtrusionSweep
2547 //=======================================================================
2549 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2550 const SMESH::DirStruct & theStepVector,
2551 CORBA::Long theNbOfSteps)
2552 throw (SALOME::SALOME_Exception)
2554 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2555 if (!myIsPreviewMode) {
2556 TPythonDump() << this << ".ExtrusionSweep( "
2557 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2561 //=======================================================================
2562 //function : ExtrusionSweep0D
2564 //=======================================================================
2566 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2567 const SMESH::DirStruct & theStepVector,
2568 CORBA::Long theNbOfSteps)
2569 throw (SALOME::SALOME_Exception)
2571 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2572 if (!myIsPreviewMode) {
2573 TPythonDump() << this << ".ExtrusionSweep0D( "
2574 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2578 //=======================================================================
2579 //function : ExtrusionSweepObject
2581 //=======================================================================
2583 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2584 const SMESH::DirStruct & theStepVector,
2585 CORBA::Long theNbOfSteps)
2586 throw (SALOME::SALOME_Exception)
2588 prepareIdSource( theObject );
2589 SMESH::long_array_var anElementsId = theObject->GetIDs();
2590 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2591 if (!myIsPreviewMode) {
2592 TPythonDump() << this << ".ExtrusionSweepObject( "
2593 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2597 //=======================================================================
2598 //function : ExtrusionSweepObject0D
2600 //=======================================================================
2602 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2603 const SMESH::DirStruct & theStepVector,
2604 CORBA::Long theNbOfSteps)
2605 throw (SALOME::SALOME_Exception)
2607 prepareIdSource( theObject );
2608 SMESH::long_array_var anElementsId = theObject->GetIDs();
2609 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2610 if ( !myIsPreviewMode ) {
2611 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2612 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2616 //=======================================================================
2617 //function : ExtrusionSweepObject1D
2619 //=======================================================================
2621 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2622 const SMESH::DirStruct & theStepVector,
2623 CORBA::Long theNbOfSteps)
2624 throw (SALOME::SALOME_Exception)
2626 prepareIdSource( theObject );
2627 SMESH::long_array_var anElementsId = theObject->GetIDs();
2628 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2629 if ( !myIsPreviewMode ) {
2630 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2631 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2635 //=======================================================================
2636 //function : ExtrusionSweepObject2D
2638 //=======================================================================
2640 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2641 const SMESH::DirStruct & theStepVector,
2642 CORBA::Long theNbOfSteps)
2643 throw (SALOME::SALOME_Exception)
2645 prepareIdSource( theObject );
2646 SMESH::long_array_var anElementsId = theObject->GetIDs();
2647 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2648 if ( !myIsPreviewMode ) {
2649 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2650 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2654 //=======================================================================
2655 //function : ExtrusionSweepMakeGroups
2657 //=======================================================================
2659 SMESH::ListOfGroups*
2660 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2661 const SMESH::DirStruct& theStepVector,
2662 CORBA::Long theNbOfSteps)
2663 throw (SALOME::SALOME_Exception)
2665 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2667 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2669 if (!myIsPreviewMode) {
2670 dumpGroupsList(aPythonDump, aGroups);
2671 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2672 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2677 //=======================================================================
2678 //function : ExtrusionSweepMakeGroups0D
2680 //=======================================================================
2682 SMESH::ListOfGroups*
2683 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2684 const SMESH::DirStruct& theStepVector,
2685 CORBA::Long theNbOfSteps)
2686 throw (SALOME::SALOME_Exception)
2688 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2690 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2692 if (!myIsPreviewMode) {
2693 dumpGroupsList(aPythonDump, aGroups);
2694 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2695 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2700 //=======================================================================
2701 //function : ExtrusionSweepObjectMakeGroups
2703 //=======================================================================
2705 SMESH::ListOfGroups*
2706 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2707 const SMESH::DirStruct& theStepVector,
2708 CORBA::Long theNbOfSteps)
2709 throw (SALOME::SALOME_Exception)
2711 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2713 prepareIdSource( theObject );
2714 SMESH::long_array_var anElementsId = theObject->GetIDs();
2715 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2717 if (!myIsPreviewMode) {
2718 dumpGroupsList(aPythonDump, aGroups);
2719 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2720 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2725 //=======================================================================
2726 //function : ExtrusionSweepObject0DMakeGroups
2728 //=======================================================================
2730 SMESH::ListOfGroups*
2731 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2732 const SMESH::DirStruct& theStepVector,
2733 CORBA::Long theNbOfSteps)
2734 throw (SALOME::SALOME_Exception)
2736 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2738 prepareIdSource( theObject );
2739 SMESH::long_array_var anElementsId = theObject->GetIDs();
2740 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2741 theNbOfSteps, true, SMDSAbs_Node);
2742 if (!myIsPreviewMode) {
2743 dumpGroupsList(aPythonDump, aGroups);
2744 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2745 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2750 //=======================================================================
2751 //function : ExtrusionSweepObject1DMakeGroups
2753 //=======================================================================
2755 SMESH::ListOfGroups*
2756 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2757 const SMESH::DirStruct& theStepVector,
2758 CORBA::Long theNbOfSteps)
2759 throw (SALOME::SALOME_Exception)
2761 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2763 prepareIdSource( theObject );
2764 SMESH::long_array_var anElementsId = theObject->GetIDs();
2765 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2766 theNbOfSteps, true, SMDSAbs_Edge);
2767 if (!myIsPreviewMode) {
2768 dumpGroupsList(aPythonDump, aGroups);
2769 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2770 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2775 //=======================================================================
2776 //function : ExtrusionSweepObject2DMakeGroups
2778 //=======================================================================
2780 SMESH::ListOfGroups*
2781 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2782 const SMESH::DirStruct& theStepVector,
2783 CORBA::Long theNbOfSteps)
2784 throw (SALOME::SALOME_Exception)
2786 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2788 prepareIdSource( theObject );
2789 SMESH::long_array_var anElementsId = theObject->GetIDs();
2790 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2791 theNbOfSteps, true, SMDSAbs_Face);
2792 if (!myIsPreviewMode) {
2793 dumpGroupsList(aPythonDump, aGroups);
2794 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2795 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2801 //=======================================================================
2802 //function : advancedExtrusion
2804 //=======================================================================
2806 SMESH::ListOfGroups*
2807 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2808 const SMESH::DirStruct & theStepVector,
2809 CORBA::Long theNbOfSteps,
2810 CORBA::Long theExtrFlags,
2811 CORBA::Double theSewTolerance,
2812 const bool theMakeGroups)
2813 throw (SALOME::SALOME_Exception)
2818 TIDSortedElemSet elements;
2819 arrayToSet(theIDsOfElements, getMeshDS(), elements);
2821 const SMESH::PointStruct * P = &theStepVector.PS;
2822 gp_Vec stepVec( P->x, P->y, P->z );
2824 TElemOfElemListMap aHystory;
2825 ::SMESH_MeshEditor::PGroupIDs groupIds =
2826 getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2827 theMakeGroups, theExtrFlags, theSewTolerance);
2829 declareMeshModified( /*isReComputeSafe=*/true );
2831 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2833 SMESH_CATCH( SMESH::throwCorbaException );
2837 //=======================================================================
2838 //function : AdvancedExtrusion
2840 //=======================================================================
2842 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2843 const SMESH::DirStruct & theStepVector,
2844 CORBA::Long theNbOfSteps,
2845 CORBA::Long theExtrFlags,
2846 CORBA::Double theSewTolerance)
2847 throw (SALOME::SALOME_Exception)
2849 if ( !myIsPreviewMode ) {
2850 TPythonDump() << "stepVector = " << theStepVector;
2851 TPythonDump() << this << ".AdvancedExtrusion("
2854 << theNbOfSteps << ","
2855 << theExtrFlags << ", "
2856 << theSewTolerance << " )";
2858 advancedExtrusion( theIDsOfElements,
2866 //=======================================================================
2867 //function : AdvancedExtrusionMakeGroups
2869 //=======================================================================
2870 SMESH::ListOfGroups*
2871 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2872 const SMESH::DirStruct& theStepVector,
2873 CORBA::Long theNbOfSteps,
2874 CORBA::Long theExtrFlags,
2875 CORBA::Double theSewTolerance)
2876 throw (SALOME::SALOME_Exception)
2878 if (!myIsPreviewMode) {
2879 TPythonDump() << "stepVector = " << theStepVector;
2881 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2883 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2890 if (!myIsPreviewMode) {
2891 dumpGroupsList(aPythonDump, aGroups);
2892 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2895 << theNbOfSteps << ","
2896 << theExtrFlags << ", "
2897 << theSewTolerance << " )";
2903 //================================================================================
2905 * \brief Convert extrusion error to IDL enum
2907 //================================================================================
2909 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2911 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2915 RETCASE( EXTR_NO_ELEMENTS );
2916 RETCASE( EXTR_PATH_NOT_EDGE );
2917 RETCASE( EXTR_BAD_PATH_SHAPE );
2918 RETCASE( EXTR_BAD_STARTING_NODE );
2919 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2920 RETCASE( EXTR_CANT_GET_TANGENT );
2922 return SMESH::SMESH_MeshEditor::EXTR_OK;
2926 //=======================================================================
2927 //function : extrusionAlongPath
2929 //=======================================================================
2930 SMESH::ListOfGroups*
2931 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2932 SMESH::SMESH_Mesh_ptr thePathMesh,
2933 GEOM::GEOM_Object_ptr thePathShape,
2934 CORBA::Long theNodeStart,
2935 CORBA::Boolean theHasAngles,
2936 const SMESH::double_array & theAngles,
2937 CORBA::Boolean theHasRefPoint,
2938 const SMESH::PointStruct & theRefPoint,
2939 const bool theMakeGroups,
2940 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2941 const SMDSAbs_ElementType theElementType)
2942 throw (SALOME::SALOME_Exception)
2945 MESSAGE("extrusionAlongPath");
2948 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2949 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2952 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2954 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2955 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2957 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2958 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2962 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2964 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2968 TIDSortedElemSet elements;
2969 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2971 list<double> angles;
2972 for (int i = 0; i < theAngles.length(); i++) {
2973 angles.push_back( theAngles[i] );
2976 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2978 int nbOldGroups = myMesh->NbGroup();
2980 ::SMESH_MeshEditor::Extrusion_Error error =
2981 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
2982 theHasAngles, angles, false,
2983 theHasRefPoint, refPnt, theMakeGroups );
2985 declareMeshModified( /*isReComputeSafe=*/true );
2986 theError = convExtrError( error );
2988 if ( theMakeGroups ) {
2989 list<int> groupIDs = myMesh->GetGroupIds();
2990 list<int>::iterator newBegin = groupIDs.begin();
2991 std::advance( newBegin, nbOldGroups ); // skip old groups
2992 groupIDs.erase( groupIDs.begin(), newBegin );
2993 return getGroups( & groupIDs );
2997 SMESH_CATCH( SMESH::throwCorbaException );
3001 //=======================================================================
3002 //function : extrusionAlongPathX
3004 //=======================================================================
3006 SMESH::ListOfGroups*
3007 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
3008 SMESH::SMESH_IDSource_ptr Path,
3009 CORBA::Long NodeStart,
3010 CORBA::Boolean HasAngles,
3011 const SMESH::double_array& Angles,
3012 CORBA::Boolean LinearVariation,
3013 CORBA::Boolean HasRefPoint,
3014 const SMESH::PointStruct& RefPoint,
3016 const SMDSAbs_ElementType ElementType,
3017 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
3018 throw (SALOME::SALOME_Exception)
3021 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
3025 list<double> angles;
3026 for (int i = 0; i < Angles.length(); i++) {
3027 angles.push_back( Angles[i] );
3029 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
3030 int nbOldGroups = myMesh->NbGroup();
3032 if ( Path->_is_nil() ) {
3033 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3037 TIDSortedElemSet elements, copyElements;
3038 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
3040 TIDSortedElemSet* workElements = &elements;
3042 if ( myIsPreviewMode )
3044 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
3045 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
3046 workElements = & copyElements;
3050 ::SMESH_MeshEditor::Extrusion_Error error;
3052 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
3055 SMDS_MeshNode* aNodeStart =
3056 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3057 if ( !aNodeStart ) {
3058 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3061 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
3062 HasAngles, angles, LinearVariation,
3063 HasRefPoint, refPnt, MakeGroups );
3064 declareMeshModified( /*isReComputeSafe=*/true );
3066 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
3069 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
3070 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
3071 SMDS_MeshNode* aNodeStart =
3072 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3073 if ( !aNodeStart ) {
3074 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3077 SMESH_subMesh* aSubMesh =
3078 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
3079 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
3080 HasAngles, angles, LinearVariation,
3081 HasRefPoint, refPnt, MakeGroups );
3082 declareMeshModified( /*isReComputeSafe=*/true );
3084 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
3086 // path as group of 1D elements
3092 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3096 Error = convExtrError( error );
3099 list<int> groupIDs = myMesh->GetGroupIds();
3100 list<int>::iterator newBegin = groupIDs.begin();
3101 std::advance( newBegin, nbOldGroups ); // skip old groups
3102 groupIDs.erase( groupIDs.begin(), newBegin );
3103 return getGroups( & groupIDs );
3107 SMESH_CATCH( SMESH::throwCorbaException );
3111 //=======================================================================
3112 //function : ExtrusionAlongPath
3114 //=======================================================================
3116 SMESH::SMESH_MeshEditor::Extrusion_Error
3117 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3118 SMESH::SMESH_Mesh_ptr thePathMesh,
3119 GEOM::GEOM_Object_ptr thePathShape,
3120 CORBA::Long theNodeStart,
3121 CORBA::Boolean theHasAngles,
3122 const SMESH::double_array & theAngles,
3123 CORBA::Boolean theHasRefPoint,
3124 const SMESH::PointStruct & theRefPoint)
3125 throw (SALOME::SALOME_Exception)
3127 MESSAGE("ExtrusionAlongPath");
3128 if ( !myIsPreviewMode ) {
3129 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
3130 << theIDsOfElements << ", "
3131 << thePathMesh << ", "
3132 << thePathShape << ", "
3133 << theNodeStart << ", "
3134 << theHasAngles << ", "
3135 << theAngles << ", "
3136 << theHasRefPoint << ", "
3137 << "SMESH.PointStruct( "
3138 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3139 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3140 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3142 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3143 extrusionAlongPath( theIDsOfElements,
3156 //=======================================================================
3157 //function : ExtrusionAlongPathObject
3159 //=======================================================================
3161 SMESH::SMESH_MeshEditor::Extrusion_Error
3162 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
3163 SMESH::SMESH_Mesh_ptr thePathMesh,
3164 GEOM::GEOM_Object_ptr thePathShape,
3165 CORBA::Long theNodeStart,
3166 CORBA::Boolean theHasAngles,
3167 const SMESH::double_array & theAngles,
3168 CORBA::Boolean theHasRefPoint,
3169 const SMESH::PointStruct & theRefPoint)
3170 throw (SALOME::SALOME_Exception)
3172 if ( !myIsPreviewMode ) {
3173 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
3174 << theObject << ", "
3175 << thePathMesh << ", "
3176 << thePathShape << ", "
3177 << theNodeStart << ", "
3178 << theHasAngles << ", "
3179 << theAngles << ", "
3180 << theHasRefPoint << ", "
3181 << "SMESH.PointStruct( "
3182 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3183 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3184 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3186 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3187 prepareIdSource( theObject );
3188 SMESH::long_array_var anElementsId = theObject->GetIDs();
3189 extrusionAlongPath( anElementsId,
3202 //=======================================================================
3203 //function : ExtrusionAlongPathObject1D
3205 //=======================================================================
3207 SMESH::SMESH_MeshEditor::Extrusion_Error
3208 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
3209 SMESH::SMESH_Mesh_ptr thePathMesh,
3210 GEOM::GEOM_Object_ptr thePathShape,
3211 CORBA::Long theNodeStart,
3212 CORBA::Boolean theHasAngles,
3213 const SMESH::double_array & theAngles,
3214 CORBA::Boolean theHasRefPoint,
3215 const SMESH::PointStruct & theRefPoint)
3216 throw (SALOME::SALOME_Exception)
3218 if ( !myIsPreviewMode ) {
3219 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
3220 << theObject << ", "
3221 << thePathMesh << ", "
3222 << thePathShape << ", "
3223 << theNodeStart << ", "
3224 << theHasAngles << ", "
3225 << theAngles << ", "
3226 << theHasRefPoint << ", "
3227 << "SMESH.PointStruct( "
3228 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3229 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3230 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3232 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3233 prepareIdSource( theObject );
3234 SMESH::long_array_var anElementsId = theObject->GetIDs();
3235 extrusionAlongPath( anElementsId,
3249 //=======================================================================
3250 //function : ExtrusionAlongPathObject2D
3252 //=======================================================================
3254 SMESH::SMESH_MeshEditor::Extrusion_Error
3255 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3256 SMESH::SMESH_Mesh_ptr thePathMesh,
3257 GEOM::GEOM_Object_ptr thePathShape,
3258 CORBA::Long theNodeStart,
3259 CORBA::Boolean theHasAngles,
3260 const SMESH::double_array & theAngles,
3261 CORBA::Boolean theHasRefPoint,
3262 const SMESH::PointStruct & theRefPoint)
3263 throw (SALOME::SALOME_Exception)
3265 if ( !myIsPreviewMode ) {
3266 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3267 << theObject << ", "
3268 << thePathMesh << ", "
3269 << thePathShape << ", "
3270 << theNodeStart << ", "
3271 << theHasAngles << ", "
3272 << theAngles << ", "
3273 << theHasRefPoint << ", "
3274 << "SMESH.PointStruct( "
3275 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3276 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3277 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3279 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3280 prepareIdSource( theObject );
3281 SMESH::long_array_var anElementsId = theObject->GetIDs();
3282 extrusionAlongPath( anElementsId,
3297 //=======================================================================
3298 //function : ExtrusionAlongPathMakeGroups
3300 //=======================================================================
3302 SMESH::ListOfGroups*
3303 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3304 SMESH::SMESH_Mesh_ptr thePathMesh,
3305 GEOM::GEOM_Object_ptr thePathShape,
3306 CORBA::Long theNodeStart,
3307 CORBA::Boolean theHasAngles,
3308 const SMESH::double_array& theAngles,
3309 CORBA::Boolean theHasRefPoint,
3310 const SMESH::PointStruct& theRefPoint,
3311 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3312 throw (SALOME::SALOME_Exception)
3314 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3316 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3326 if (!myIsPreviewMode) {
3327 bool isDumpGroups = aGroups && aGroups->length() > 0;
3329 aPythonDump << "(" << aGroups << ", error)";
3331 aPythonDump <<"error";
3333 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3334 << theIDsOfElements << ", "
3335 << thePathMesh << ", "
3336 << thePathShape << ", "
3337 << theNodeStart << ", "
3338 << theHasAngles << ", "
3339 << theAngles << ", "
3340 << theHasRefPoint << ", "
3341 << "SMESH.PointStruct( "
3342 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3343 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3344 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3349 //=======================================================================
3350 //function : ExtrusionAlongPathObjectMakeGroups
3352 //=======================================================================
3354 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3355 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3356 SMESH::SMESH_Mesh_ptr thePathMesh,
3357 GEOM::GEOM_Object_ptr thePathShape,
3358 CORBA::Long theNodeStart,
3359 CORBA::Boolean theHasAngles,
3360 const SMESH::double_array& theAngles,
3361 CORBA::Boolean theHasRefPoint,
3362 const SMESH::PointStruct& theRefPoint,
3363 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3364 throw (SALOME::SALOME_Exception)
3366 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3368 prepareIdSource( theObject );
3369 SMESH::long_array_var anElementsId = theObject->GetIDs();
3370 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3381 if (!myIsPreviewMode) {
3382 bool isDumpGroups = aGroups && aGroups->length() > 0;
3384 aPythonDump << "(" << aGroups << ", error)";
3386 aPythonDump <<"error";
3388 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3389 << theObject << ", "
3390 << thePathMesh << ", "
3391 << thePathShape << ", "
3392 << theNodeStart << ", "
3393 << theHasAngles << ", "
3394 << theAngles << ", "
3395 << theHasRefPoint << ", "
3396 << "SMESH.PointStruct( "
3397 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3398 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3399 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3404 //=======================================================================
3405 //function : ExtrusionAlongPathObject1DMakeGroups
3407 //=======================================================================
3409 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3410 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3411 SMESH::SMESH_Mesh_ptr thePathMesh,
3412 GEOM::GEOM_Object_ptr thePathShape,
3413 CORBA::Long theNodeStart,
3414 CORBA::Boolean theHasAngles,
3415 const SMESH::double_array& theAngles,
3416 CORBA::Boolean theHasRefPoint,
3417 const SMESH::PointStruct& theRefPoint,
3418 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3419 throw (SALOME::SALOME_Exception)
3421 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3423 prepareIdSource( theObject );
3424 SMESH::long_array_var anElementsId = theObject->GetIDs();
3425 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3437 if (!myIsPreviewMode) {
3438 bool isDumpGroups = aGroups && aGroups->length() > 0;
3440 aPythonDump << "(" << aGroups << ", error)";
3442 aPythonDump << "error";
3444 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3445 << theObject << ", "
3446 << thePathMesh << ", "
3447 << thePathShape << ", "
3448 << theNodeStart << ", "
3449 << theHasAngles << ", "
3450 << theAngles << ", "
3451 << theHasRefPoint << ", "
3452 << "SMESH.PointStruct( "
3453 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3454 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3455 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3460 //=======================================================================
3461 //function : ExtrusionAlongPathObject2DMakeGroups
3463 //=======================================================================
3465 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3466 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3467 SMESH::SMESH_Mesh_ptr thePathMesh,
3468 GEOM::GEOM_Object_ptr thePathShape,
3469 CORBA::Long theNodeStart,
3470 CORBA::Boolean theHasAngles,
3471 const SMESH::double_array& theAngles,
3472 CORBA::Boolean theHasRefPoint,
3473 const SMESH::PointStruct& theRefPoint,
3474 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3475 throw (SALOME::SALOME_Exception)
3477 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3479 prepareIdSource( theObject );
3480 SMESH::long_array_var anElementsId = theObject->GetIDs();
3481 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3493 if (!myIsPreviewMode) {
3494 bool isDumpGroups = aGroups && aGroups->length() > 0;
3496 aPythonDump << "(" << aGroups << ", error)";
3498 aPythonDump << "error";
3500 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3501 << theObject << ", "
3502 << thePathMesh << ", "
3503 << thePathShape << ", "
3504 << theNodeStart << ", "
3505 << theHasAngles << ", "
3506 << theAngles << ", "
3507 << theHasRefPoint << ", "
3508 << "SMESH.PointStruct( "
3509 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3510 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3511 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3516 //=======================================================================
3517 //function : ExtrusionAlongPathObjX
3519 //=======================================================================
3521 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3522 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3523 SMESH::SMESH_IDSource_ptr Path,
3524 CORBA::Long NodeStart,
3525 CORBA::Boolean HasAngles,
3526 const SMESH::double_array& Angles,
3527 CORBA::Boolean LinearVariation,
3528 CORBA::Boolean HasRefPoint,
3529 const SMESH::PointStruct& RefPoint,
3530 CORBA::Boolean MakeGroups,
3531 SMESH::ElementType ElemType,
3532 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3533 throw (SALOME::SALOME_Exception)
3535 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3537 prepareIdSource( Object );
3538 SMESH::long_array_var anElementsId = Object->GetIDs();
3539 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3548 (SMDSAbs_ElementType)ElemType,
3551 if (!myIsPreviewMode) {
3552 bool isDumpGroups = aGroups && aGroups->length() > 0;
3554 aPythonDump << "(" << *aGroups << ", error)";
3556 aPythonDump << "error";
3558 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3561 << NodeStart << ", "
3562 << HasAngles << ", "
3563 << TVar( Angles ) << ", "
3564 << LinearVariation << ", "
3565 << HasRefPoint << ", "
3566 << "SMESH.PointStruct( "
3567 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3568 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3569 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3570 << MakeGroups << ", "
3571 << ElemType << " )";
3576 //=======================================================================
3577 //function : ExtrusionAlongPathX
3579 //=======================================================================
3581 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3582 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3583 SMESH::SMESH_IDSource_ptr Path,
3584 CORBA::Long NodeStart,
3585 CORBA::Boolean HasAngles,
3586 const SMESH::double_array& Angles,
3587 CORBA::Boolean LinearVariation,
3588 CORBA::Boolean HasRefPoint,
3589 const SMESH::PointStruct& RefPoint,
3590 CORBA::Boolean MakeGroups,
3591 SMESH::ElementType ElemType,
3592 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3593 throw (SALOME::SALOME_Exception)
3595 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3597 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3606 (SMDSAbs_ElementType)ElemType,
3609 if (!myIsPreviewMode) {
3610 bool isDumpGroups = aGroups && aGroups->length() > 0;
3612 aPythonDump << "(" << *aGroups << ", error)";
3614 aPythonDump <<"error";
3616 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3617 << IDsOfElements << ", "
3619 << NodeStart << ", "
3620 << HasAngles << ", "
3621 << TVar( Angles ) << ", "
3622 << LinearVariation << ", "
3623 << HasRefPoint << ", "
3624 << "SMESH.PointStruct( "
3625 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3626 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3627 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3628 << MakeGroups << ", "
3629 << ElemType << " )";
3634 //================================================================================
3636 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3637 * of given angles along path steps
3638 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3639 * which proceeds the extrusion
3640 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3641 * is used to define the sub-mesh for the path
3643 //================================================================================
3645 SMESH::double_array*
3646 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3647 GEOM::GEOM_Object_ptr thePathShape,
3648 const SMESH::double_array & theAngles)
3650 SMESH::double_array_var aResult = new SMESH::double_array();
3651 int nbAngles = theAngles.length();
3652 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3654 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3655 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3656 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3657 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3658 return aResult._retn();
3659 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3660 if ( nbSteps == nbAngles )
3662 aResult.inout() = theAngles;
3666 aResult->length( nbSteps );
3667 double rAn2St = double( nbAngles ) / double( nbSteps );
3668 double angPrev = 0, angle;
3669 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3671 double angCur = rAn2St * ( iSt+1 );
3672 double angCurFloor = floor( angCur );
3673 double angPrevFloor = floor( angPrev );
3674 if ( angPrevFloor == angCurFloor )
3675 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3678 int iP = int( angPrevFloor );
3679 double angPrevCeil = ceil(angPrev);
3680 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3682 int iC = int( angCurFloor );
3683 if ( iC < nbAngles )
3684 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3686 iP = int( angPrevCeil );
3688 angle += theAngles[ iC ];
3690 aResult[ iSt ] = angle;
3695 // Update Python script
3696 TPythonDump() << "rotAngles = " << theAngles;
3697 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3698 << thePathMesh << ", "
3699 << thePathShape << ", "
3702 return aResult._retn();
3705 //=======================================================================
3708 //=======================================================================
3710 SMESH::ListOfGroups*
3711 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3712 const SMESH::AxisStruct & theAxis,
3713 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3714 CORBA::Boolean theCopy,
3716 ::SMESH_Mesh* theTargetMesh)
3717 throw (SALOME::SALOME_Exception)
3722 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3723 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3725 if ( theTargetMesh )
3729 switch ( theMirrorType ) {
3730 case SMESH::SMESH_MeshEditor::POINT:
3731 aTrsf.SetMirror( P );
3733 case SMESH::SMESH_MeshEditor::AXIS:
3734 aTrsf.SetMirror( gp_Ax1( P, V ));
3737 aTrsf.SetMirror( gp_Ax2( P, V ));
3740 TIDSortedElemSet copyElements;
3741 TIDSortedElemSet* workElements = & theElements;
3743 if ( myIsPreviewMode )
3745 TPreviewMesh * tmpMesh = getPreviewMesh();
3746 tmpMesh->Copy( theElements, copyElements);
3747 if ( !theCopy && !theTargetMesh )
3749 TIDSortedElemSet elemsAround, elemsAroundCopy;
3750 getElementsAround( theElements, getMeshDS(), elemsAround );
3751 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3753 workElements = & copyElements;
3754 theMakeGroups = false;
3757 ::SMESH_MeshEditor::PGroupIDs groupIds =
3758 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3760 if ( theCopy && !myIsPreviewMode)
3762 if ( theTargetMesh )
3764 theTargetMesh->GetMeshDS()->Modified();
3768 declareMeshModified( /*isReComputeSafe=*/false );
3771 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3773 SMESH_CATCH( SMESH::throwCorbaException );
3777 //=======================================================================
3780 //=======================================================================
3782 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3783 const SMESH::AxisStruct & theAxis,
3784 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3785 CORBA::Boolean theCopy)
3786 throw (SALOME::SALOME_Exception)
3788 if ( !myIsPreviewMode ) {
3789 TPythonDump() << this << ".Mirror( "
3790 << theIDsOfElements << ", "
3792 << mirrorTypeName(theMirrorType) << ", "
3795 if ( theIDsOfElements.length() > 0 )
3797 TIDSortedElemSet elements;
3798 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3799 mirror(elements, theAxis, theMirrorType, theCopy, false);
3804 //=======================================================================
3805 //function : MirrorObject
3807 //=======================================================================
3809 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3810 const SMESH::AxisStruct & theAxis,
3811 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3812 CORBA::Boolean theCopy)
3813 throw (SALOME::SALOME_Exception)
3815 if ( !myIsPreviewMode ) {
3816 TPythonDump() << this << ".MirrorObject( "
3817 << theObject << ", "
3819 << mirrorTypeName(theMirrorType) << ", "
3822 TIDSortedElemSet elements;
3824 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3826 prepareIdSource( theObject );
3827 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3828 mirror(elements, theAxis, theMirrorType, theCopy, false);
3831 //=======================================================================
3832 //function : MirrorMakeGroups
3834 //=======================================================================
3836 SMESH::ListOfGroups*
3837 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3838 const SMESH::AxisStruct& theMirror,
3839 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3840 throw (SALOME::SALOME_Exception)
3842 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3844 SMESH::ListOfGroups * aGroups = 0;
3845 if ( theIDsOfElements.length() > 0 )
3847 TIDSortedElemSet elements;
3848 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3849 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3851 if (!myIsPreviewMode) {
3852 dumpGroupsList(aPythonDump, aGroups);
3853 aPythonDump << this << ".MirrorMakeGroups( "
3854 << theIDsOfElements << ", "
3855 << theMirror << ", "
3856 << mirrorTypeName(theMirrorType) << " )";
3861 //=======================================================================
3862 //function : MirrorObjectMakeGroups
3864 //=======================================================================
3866 SMESH::ListOfGroups*
3867 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3868 const SMESH::AxisStruct& theMirror,
3869 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3870 throw (SALOME::SALOME_Exception)
3872 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3874 SMESH::ListOfGroups * aGroups = 0;
3875 TIDSortedElemSet elements;
3876 prepareIdSource( theObject );
3877 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3878 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3880 if (!myIsPreviewMode)
3882 dumpGroupsList(aPythonDump,aGroups);
3883 aPythonDump << this << ".MirrorObjectMakeGroups( "
3884 << theObject << ", "
3885 << theMirror << ", "
3886 << mirrorTypeName(theMirrorType) << " )";
3891 //=======================================================================
3892 //function : MirrorMakeMesh
3894 //=======================================================================
3896 SMESH::SMESH_Mesh_ptr
3897 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3898 const SMESH::AxisStruct& theMirror,
3899 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3900 CORBA::Boolean theCopyGroups,
3901 const char* theMeshName)
3902 throw (SALOME::SALOME_Exception)
3904 SMESH_Mesh_i* mesh_i;
3905 SMESH::SMESH_Mesh_var mesh;
3906 { // open new scope to dump "MakeMesh" command
3907 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3909 TPythonDump pydump; // to prevent dump at mesh creation
3911 mesh = makeMesh( theMeshName );
3912 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3913 if (mesh_i && theIDsOfElements.length() > 0 )
3915 TIDSortedElemSet elements;
3916 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3917 mirror(elements, theMirror, theMirrorType,
3918 false, theCopyGroups, & mesh_i->GetImpl());
3919 mesh_i->CreateGroupServants();
3922 if (!myIsPreviewMode) {
3923 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3924 << theIDsOfElements << ", "
3925 << theMirror << ", "
3926 << mirrorTypeName(theMirrorType) << ", "
3927 << theCopyGroups << ", '"
3928 << theMeshName << "' )";
3933 if (!myIsPreviewMode && mesh_i)
3934 mesh_i->GetGroups();
3936 return mesh._retn();
3939 //=======================================================================
3940 //function : MirrorObjectMakeMesh
3942 //=======================================================================
3944 SMESH::SMESH_Mesh_ptr
3945 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3946 const SMESH::AxisStruct& theMirror,
3947 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3948 CORBA::Boolean theCopyGroups,
3949 const char* theMeshName)
3950 throw (SALOME::SALOME_Exception)
3952 SMESH_Mesh_i* mesh_i;
3953 SMESH::SMESH_Mesh_var mesh;
3954 { // open new scope to dump "MakeMesh" command
3955 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3957 TPythonDump pydump; // to prevent dump at mesh creation
3959 mesh = makeMesh( theMeshName );
3960 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3961 TIDSortedElemSet elements;
3962 prepareIdSource( theObject );
3964 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3966 mirror(elements, theMirror, theMirrorType,
3967 false, theCopyGroups, & mesh_i->GetImpl());
3968 mesh_i->CreateGroupServants();
3970 if (!myIsPreviewMode) {
3971 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3972 << theObject << ", "
3973 << theMirror << ", "
3974 << mirrorTypeName(theMirrorType) << ", "
3975 << theCopyGroups << ", '"
3976 << theMeshName << "' )";
3981 if (!myIsPreviewMode && mesh_i)
3982 mesh_i->GetGroups();
3984 return mesh._retn();
3987 //=======================================================================
3988 //function : translate
3990 //=======================================================================
3992 SMESH::ListOfGroups*
3993 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3994 const SMESH::DirStruct & theVector,
3995 CORBA::Boolean theCopy,
3997 ::SMESH_Mesh* theTargetMesh)
3998 throw (SALOME::SALOME_Exception)
4003 if ( theTargetMesh )
4007 const SMESH::PointStruct * P = &theVector.PS;
4008 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
4010 TIDSortedElemSet copyElements;
4011 TIDSortedElemSet* workElements = &theElements;
4013 if ( myIsPreviewMode )
4015 TPreviewMesh * tmpMesh = getPreviewMesh();
4016 tmpMesh->Copy( theElements, copyElements);
4017 if ( !theCopy && !theTargetMesh )
4019 TIDSortedElemSet elemsAround, elemsAroundCopy;
4020 getElementsAround( theElements, getMeshDS(), elemsAround );
4021 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4023 workElements = & copyElements;
4024 theMakeGroups = false;
4027 ::SMESH_MeshEditor::PGroupIDs groupIds =
4028 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4030 if ( theCopy && !myIsPreviewMode )
4032 if ( theTargetMesh )
4034 theTargetMesh->GetMeshDS()->Modified();
4038 declareMeshModified( /*isReComputeSafe=*/false );
4042 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4044 SMESH_CATCH( SMESH::throwCorbaException );
4048 //=======================================================================
4049 //function : Translate
4051 //=======================================================================
4053 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
4054 const SMESH::DirStruct & theVector,
4055 CORBA::Boolean theCopy)
4056 throw (SALOME::SALOME_Exception)
4058 if (!myIsPreviewMode) {
4059 TPythonDump() << this << ".Translate( "
4060 << theIDsOfElements << ", "
4061 << theVector << ", "
4064 if (theIDsOfElements.length()) {
4065 TIDSortedElemSet elements;
4066 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4067 translate(elements, theVector, theCopy, false);
4071 //=======================================================================
4072 //function : TranslateObject
4074 //=======================================================================
4076 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
4077 const SMESH::DirStruct & theVector,
4078 CORBA::Boolean theCopy)
4079 throw (SALOME::SALOME_Exception)
4081 if (!myIsPreviewMode) {
4082 TPythonDump() << this << ".TranslateObject( "
4083 << theObject << ", "
4084 << theVector << ", "
4087 TIDSortedElemSet elements;
4089 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4091 prepareIdSource( theObject );
4092 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4093 translate(elements, theVector, theCopy, false);
4096 //=======================================================================
4097 //function : TranslateMakeGroups
4099 //=======================================================================
4101 SMESH::ListOfGroups*
4102 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
4103 const SMESH::DirStruct& theVector)
4104 throw (SALOME::SALOME_Exception)
4106 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4108 SMESH::ListOfGroups * aGroups = 0;
4109 if (theIDsOfElements.length()) {
4110 TIDSortedElemSet elements;
4111 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4112 aGroups = translate(elements,theVector,true,true);
4114 if (!myIsPreviewMode) {
4115 dumpGroupsList(aPythonDump, aGroups);
4116 aPythonDump << this << ".TranslateMakeGroups( "
4117 << theIDsOfElements << ", "
4118 << theVector << " )";
4123 //=======================================================================
4124 //function : TranslateObjectMakeGroups
4126 //=======================================================================
4128 SMESH::ListOfGroups*
4129 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4130 const SMESH::DirStruct& theVector)
4131 throw (SALOME::SALOME_Exception)
4133 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4135 SMESH::ListOfGroups * aGroups = 0;
4136 TIDSortedElemSet elements;
4137 prepareIdSource( theObject );
4138 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4139 aGroups = translate(elements, theVector, true, true);
4141 if (!myIsPreviewMode) {
4142 dumpGroupsList(aPythonDump, aGroups);
4143 aPythonDump << this << ".TranslateObjectMakeGroups( "
4144 << theObject << ", "
4145 << theVector << " )";
4150 //=======================================================================
4151 //function : TranslateMakeMesh
4153 //=======================================================================
4155 SMESH::SMESH_Mesh_ptr
4156 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
4157 const SMESH::DirStruct& theVector,
4158 CORBA::Boolean theCopyGroups,
4159 const char* theMeshName)
4160 throw (SALOME::SALOME_Exception)
4162 SMESH_Mesh_i* mesh_i;
4163 SMESH::SMESH_Mesh_var mesh;
4165 { // open new scope to dump "MakeMesh" command
4166 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4168 TPythonDump pydump; // to prevent dump at mesh creation
4170 mesh = makeMesh( theMeshName );
4171 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4173 if ( mesh_i && theIDsOfElements.length() )
4175 TIDSortedElemSet elements;
4176 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4177 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
4178 mesh_i->CreateGroupServants();
4181 if ( !myIsPreviewMode ) {
4182 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
4183 << theIDsOfElements << ", "
4184 << theVector << ", "
4185 << theCopyGroups << ", '"
4186 << theMeshName << "' )";
4191 if (!myIsPreviewMode && mesh_i)
4192 mesh_i->GetGroups();
4194 return mesh._retn();
4197 //=======================================================================
4198 //function : TranslateObjectMakeMesh
4200 //=======================================================================
4202 SMESH::SMESH_Mesh_ptr
4203 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4204 const SMESH::DirStruct& theVector,
4205 CORBA::Boolean theCopyGroups,
4206 const char* theMeshName)
4207 throw (SALOME::SALOME_Exception)
4210 SMESH_Mesh_i* mesh_i;
4211 SMESH::SMESH_Mesh_var mesh;
4212 { // open new scope to dump "MakeMesh" command
4213 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4215 TPythonDump pydump; // to prevent dump at mesh creation
4216 mesh = makeMesh( theMeshName );
4217 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4219 TIDSortedElemSet elements;
4220 prepareIdSource( theObject );
4222 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4224 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
4225 mesh_i->CreateGroupServants();
4227 if ( !myIsPreviewMode ) {
4228 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
4229 << theObject << ", "
4230 << theVector << ", "
4231 << theCopyGroups << ", '"
4232 << theMeshName << "' )";
4237 if (!myIsPreviewMode && mesh_i)
4238 mesh_i->GetGroups();
4240 return mesh._retn();
4242 SMESH_CATCH( SMESH::throwCorbaException );
4246 //=======================================================================
4249 //=======================================================================
4251 SMESH::ListOfGroups*
4252 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
4253 const SMESH::AxisStruct & theAxis,
4254 CORBA::Double theAngle,
4255 CORBA::Boolean theCopy,
4257 ::SMESH_Mesh* theTargetMesh)
4258 throw (SALOME::SALOME_Exception)
4263 if ( theTargetMesh )
4266 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
4267 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
4270 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
4272 TIDSortedElemSet copyElements;
4273 TIDSortedElemSet* workElements = &theElements;
4274 if ( myIsPreviewMode ) {
4275 TPreviewMesh * tmpMesh = getPreviewMesh();
4276 tmpMesh->Copy( theElements, copyElements );
4277 if ( !theCopy && !theTargetMesh )
4279 TIDSortedElemSet elemsAround, elemsAroundCopy;
4280 getElementsAround( theElements, getMeshDS(), elemsAround );
4281 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4283 workElements = ©Elements;
4284 theMakeGroups = false;
4287 ::SMESH_MeshEditor::PGroupIDs groupIds =
4288 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4290 if ( theCopy && !myIsPreviewMode)
4292 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4293 else declareMeshModified( /*isReComputeSafe=*/false );
4296 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4298 SMESH_CATCH( SMESH::throwCorbaException );
4302 //=======================================================================
4305 //=======================================================================
4307 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4308 const SMESH::AxisStruct & theAxis,
4309 CORBA::Double theAngle,
4310 CORBA::Boolean theCopy)
4311 throw (SALOME::SALOME_Exception)
4313 if (!myIsPreviewMode) {
4314 TPythonDump() << this << ".Rotate( "
4315 << theIDsOfElements << ", "
4317 << TVar( theAngle ) << ", "
4320 if (theIDsOfElements.length() > 0)
4322 TIDSortedElemSet elements;
4323 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4324 rotate(elements,theAxis,theAngle,theCopy,false);
4328 //=======================================================================
4329 //function : RotateObject
4331 //=======================================================================
4333 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4334 const SMESH::AxisStruct & theAxis,
4335 CORBA::Double theAngle,
4336 CORBA::Boolean theCopy)
4337 throw (SALOME::SALOME_Exception)
4339 if ( !myIsPreviewMode ) {
4340 TPythonDump() << this << ".RotateObject( "
4341 << theObject << ", "
4343 << TVar( theAngle ) << ", "
4346 TIDSortedElemSet elements;
4347 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4348 prepareIdSource( theObject );
4349 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4350 rotate(elements,theAxis,theAngle,theCopy,false);
4353 //=======================================================================
4354 //function : RotateMakeGroups
4356 //=======================================================================
4358 SMESH::ListOfGroups*
4359 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4360 const SMESH::AxisStruct& theAxis,
4361 CORBA::Double theAngle)
4362 throw (SALOME::SALOME_Exception)
4364 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4366 SMESH::ListOfGroups * aGroups = 0;
4367 if (theIDsOfElements.length() > 0)
4369 TIDSortedElemSet elements;
4370 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4371 aGroups = rotate(elements,theAxis,theAngle,true,true);
4373 if (!myIsPreviewMode) {
4374 dumpGroupsList(aPythonDump, aGroups);
4375 aPythonDump << this << ".RotateMakeGroups( "
4376 << theIDsOfElements << ", "
4378 << TVar( theAngle ) << " )";
4383 //=======================================================================
4384 //function : RotateObjectMakeGroups
4386 //=======================================================================
4388 SMESH::ListOfGroups*
4389 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4390 const SMESH::AxisStruct& theAxis,
4391 CORBA::Double theAngle)
4392 throw (SALOME::SALOME_Exception)
4394 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4396 SMESH::ListOfGroups * aGroups = 0;
4397 TIDSortedElemSet elements;
4398 prepareIdSource( theObject );
4399 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4400 aGroups = rotate(elements, theAxis, theAngle, true, true);
4402 if (!myIsPreviewMode) {
4403 dumpGroupsList(aPythonDump, aGroups);
4404 aPythonDump << this << ".RotateObjectMakeGroups( "
4405 << theObject << ", "
4407 << TVar( theAngle ) << " )";
4412 //=======================================================================
4413 //function : RotateMakeMesh
4415 //=======================================================================
4417 SMESH::SMESH_Mesh_ptr
4418 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4419 const SMESH::AxisStruct& theAxis,
4420 CORBA::Double theAngleInRadians,
4421 CORBA::Boolean theCopyGroups,
4422 const char* theMeshName)
4423 throw (SALOME::SALOME_Exception)
4426 SMESH::SMESH_Mesh_var mesh;
4427 SMESH_Mesh_i* mesh_i;
4429 { // open new scope to dump "MakeMesh" command
4430 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4432 TPythonDump pydump; // to prevent dump at mesh creation
4434 mesh = makeMesh( theMeshName );
4435 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4437 if ( mesh_i && theIDsOfElements.length() > 0 )
4439 TIDSortedElemSet elements;
4440 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4441 rotate(elements, theAxis, theAngleInRadians,
4442 false, theCopyGroups, & mesh_i->GetImpl());
4443 mesh_i->CreateGroupServants();
4445 if ( !myIsPreviewMode ) {
4446 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4447 << theIDsOfElements << ", "
4449 << TVar( theAngleInRadians ) << ", "
4450 << theCopyGroups << ", '"
4451 << theMeshName << "' )";
4456 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4457 mesh_i->GetGroups();
4459 return mesh._retn();
4461 SMESH_CATCH( SMESH::throwCorbaException );
4465 //=======================================================================
4466 //function : RotateObjectMakeMesh
4468 //=======================================================================
4470 SMESH::SMESH_Mesh_ptr
4471 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4472 const SMESH::AxisStruct& theAxis,
4473 CORBA::Double theAngleInRadians,
4474 CORBA::Boolean theCopyGroups,
4475 const char* theMeshName)
4476 throw (SALOME::SALOME_Exception)
4479 SMESH::SMESH_Mesh_var mesh;
4480 SMESH_Mesh_i* mesh_i;
4482 {// open new scope to dump "MakeMesh" command
4483 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4485 TPythonDump pydump; // to prevent dump at mesh creation
4486 mesh = makeMesh( theMeshName );
4487 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4489 TIDSortedElemSet elements;
4490 prepareIdSource( theObject );
4492 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4494 rotate(elements, theAxis, theAngleInRadians,
4495 false, theCopyGroups, & mesh_i->GetImpl());
4496 mesh_i->CreateGroupServants();
4498 if ( !myIsPreviewMode ) {
4499 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4500 << theObject << ", "
4502 << TVar( theAngleInRadians ) << ", "
4503 << theCopyGroups << ", '"
4504 << theMeshName << "' )";
4509 if (!myIsPreviewMode && mesh_i)
4510 mesh_i->GetGroups();
4512 return mesh._retn();
4514 SMESH_CATCH( SMESH::throwCorbaException );
4518 //=======================================================================
4521 //=======================================================================
4523 SMESH::ListOfGroups*
4524 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4525 const SMESH::PointStruct& thePoint,
4526 const SMESH::double_array& theScaleFact,
4527 CORBA::Boolean theCopy,
4529 ::SMESH_Mesh* theTargetMesh)
4530 throw (SALOME::SALOME_Exception)
4534 if ( theScaleFact.length() < 1 )
4535 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4536 if ( theScaleFact.length() == 2 )
4537 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4539 if ( theTargetMesh )
4542 TIDSortedElemSet elements;
4543 prepareIdSource( theObject );
4544 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4545 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4550 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4551 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4553 double tol = std::numeric_limits<double>::max();
4555 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4556 0, S[1], 0, thePoint.y * (1-S[1]),
4557 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4559 TIDSortedElemSet copyElements;
4560 TIDSortedElemSet* workElements = &elements;
4561 if ( myIsPreviewMode )
4563 TPreviewMesh * tmpMesh = getPreviewMesh();
4564 tmpMesh->Copy( elements, copyElements);
4565 if ( !theCopy && !theTargetMesh )
4567 TIDSortedElemSet elemsAround, elemsAroundCopy;
4568 getElementsAround( elements, getMeshDS(), elemsAround );
4569 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4571 workElements = & copyElements;
4572 theMakeGroups = false;
4575 ::SMESH_MeshEditor::PGroupIDs groupIds =
4576 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4578 if ( theCopy && !myIsPreviewMode )
4580 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4581 else declareMeshModified( /*isReComputeSafe=*/false );
4583 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4585 SMESH_CATCH( SMESH::throwCorbaException );
4589 //=======================================================================
4592 //=======================================================================
4594 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4595 const SMESH::PointStruct& thePoint,
4596 const SMESH::double_array& theScaleFact,
4597 CORBA::Boolean theCopy)
4598 throw (SALOME::SALOME_Exception)
4600 if ( !myIsPreviewMode ) {
4601 TPythonDump() << this << ".Scale( "
4602 << theObject << ", "
4604 << TVar( theScaleFact ) << ", "
4607 scale(theObject, thePoint, theScaleFact, theCopy, false);
4611 //=======================================================================
4612 //function : ScaleMakeGroups
4614 //=======================================================================
4616 SMESH::ListOfGroups*
4617 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4618 const SMESH::PointStruct& thePoint,
4619 const SMESH::double_array& theScaleFact)
4620 throw (SALOME::SALOME_Exception)
4622 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4624 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4625 if (!myIsPreviewMode) {
4626 dumpGroupsList(aPythonDump, aGroups);
4627 aPythonDump << this << ".Scale("
4630 << TVar( theScaleFact ) << ",True,True)";
4636 //=======================================================================
4637 //function : ScaleMakeMesh
4639 //=======================================================================
4641 SMESH::SMESH_Mesh_ptr
4642 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4643 const SMESH::PointStruct& thePoint,
4644 const SMESH::double_array& theScaleFact,
4645 CORBA::Boolean theCopyGroups,
4646 const char* theMeshName)
4647 throw (SALOME::SALOME_Exception)
4649 SMESH_Mesh_i* mesh_i;
4650 SMESH::SMESH_Mesh_var mesh;
4651 { // open new scope to dump "MakeMesh" command
4652 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4654 TPythonDump pydump; // to prevent dump at mesh creation
4655 mesh = makeMesh( theMeshName );
4656 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4660 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4661 mesh_i->CreateGroupServants();
4663 if ( !myIsPreviewMode )
4664 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4665 << theObject << ", "
4667 << TVar( theScaleFact ) << ", "
4668 << theCopyGroups << ", '"
4669 << theMeshName << "' )";
4673 if (!myIsPreviewMode && mesh_i)
4674 mesh_i->GetGroups();
4676 return mesh._retn();
4680 //=======================================================================
4681 //function : FindCoincidentNodes
4683 //=======================================================================
4685 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4686 SMESH::array_of_long_array_out GroupsOfNodes)
4687 throw (SALOME::SALOME_Exception)
4692 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4693 TIDSortedNodeSet nodes; // no input nodes
4694 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4696 GroupsOfNodes = new SMESH::array_of_long_array;
4697 GroupsOfNodes->length( aListOfListOfNodes.size() );
4698 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4699 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4700 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4701 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4702 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4703 aGroup.length( aListOfNodes.size() );
4704 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4705 aGroup[ j ] = (*lIt)->GetID();
4707 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4708 << Tolerance << " )";
4710 SMESH_CATCH( SMESH::throwCorbaException );
4713 //=======================================================================
4714 //function : FindCoincidentNodesOnPart
4716 //=======================================================================
4718 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4719 CORBA::Double Tolerance,
4720 SMESH::array_of_long_array_out GroupsOfNodes)
4721 throw (SALOME::SALOME_Exception)
4726 TIDSortedNodeSet nodes;
4727 prepareIdSource( theObject );
4728 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4730 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4732 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4734 GroupsOfNodes = new SMESH::array_of_long_array;
4735 GroupsOfNodes->length( aListOfListOfNodes.size() );
4736 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4737 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4739 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4740 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4741 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4742 aGroup.length( aListOfNodes.size() );
4743 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4744 aGroup[ j ] = (*lIt)->GetID();
4746 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4748 << Tolerance << " )";
4750 SMESH_CATCH( SMESH::throwCorbaException );
4753 //================================================================================
4755 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4756 * ExceptSubMeshOrGroups
4758 //================================================================================
4760 void SMESH_MeshEditor_i::
4761 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4762 CORBA::Double theTolerance,
4763 SMESH::array_of_long_array_out theGroupsOfNodes,
4764 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4765 throw (SALOME::SALOME_Exception)
4770 TIDSortedNodeSet nodes;
4771 prepareIdSource( theObject );
4772 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4774 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4776 TIDSortedNodeSet exceptNodes;
4777 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
4778 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4779 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4780 nodes.erase( *avoidNode );
4782 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4784 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4786 theGroupsOfNodes = new SMESH::array_of_long_array;
4787 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4788 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4789 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4791 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4792 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4793 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4794 aGroup.length( aListOfNodes.size() );
4795 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4796 aGroup[ j ] = (*lIt)->GetID();
4798 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4800 << theTolerance << ", "
4801 << theExceptSubMeshOrGroups << " )";
4803 SMESH_CATCH( SMESH::throwCorbaException );
4806 //=======================================================================
4807 //function : MergeNodes
4809 //=======================================================================
4811 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4812 throw (SALOME::SALOME_Exception)
4817 SMESHDS_Mesh* aMesh = getMeshDS();
4819 TPythonDump aTPythonDump;
4820 aTPythonDump << this << ".MergeNodes([";
4821 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4822 for (int i = 0; i < GroupsOfNodes.length(); i++)
4824 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4825 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4826 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4827 for ( int j = 0; j < aNodeGroup.length(); j++ )
4829 CORBA::Long index = aNodeGroup[ j ];
4830 const SMDS_MeshNode * node = aMesh->FindNode(index);
4832 aListOfNodes.push_back( node );
4834 if ( aListOfNodes.size() < 2 )
4835 aListOfListOfNodes.pop_back();
4837 if ( i > 0 ) aTPythonDump << ", ";
4838 aTPythonDump << aNodeGroup;
4840 getEditor().MergeNodes( aListOfListOfNodes );
4842 aTPythonDump << "])";
4844 declareMeshModified( /*isReComputeSafe=*/false );
4846 SMESH_CATCH( SMESH::throwCorbaException );
4849 //=======================================================================
4850 //function : FindEqualElements
4852 //=======================================================================
4854 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4855 SMESH::array_of_long_array_out GroupsOfElementsID)
4856 throw (SALOME::SALOME_Exception)
4861 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4862 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4864 TIDSortedElemSet elems;
4865 prepareIdSource( theObject );
4866 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4868 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4869 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
4871 GroupsOfElementsID = new SMESH::array_of_long_array;
4872 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4874 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4875 aListOfListOfElementsID.begin();
4876 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4878 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4879 list<int>& listOfIDs = *arraysIt;
4880 aGroup.length( listOfIDs.size() );
4881 list<int>::iterator idIt = listOfIDs.begin();
4882 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4883 aGroup[ k ] = *idIt;
4886 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4890 SMESH_CATCH( SMESH::throwCorbaException );
4893 //=======================================================================
4894 //function : MergeElements
4896 //=======================================================================
4898 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4899 throw (SALOME::SALOME_Exception)
4904 TPythonDump aTPythonDump;
4905 aTPythonDump << this << ".MergeElements( [";
4907 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4909 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4910 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4911 aListOfListOfElementsID.push_back( list< int >() );
4912 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4913 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4914 CORBA::Long id = anElemsIDGroup[ j ];
4915 aListOfElemsID.push_back( id );
4917 if ( aListOfElemsID.size() < 2 )
4918 aListOfListOfElementsID.pop_back();
4919 if ( i > 0 ) aTPythonDump << ", ";
4920 aTPythonDump << anElemsIDGroup;
4923 getEditor().MergeElements(aListOfListOfElementsID);
4925 declareMeshModified( /*isReComputeSafe=*/true );
4927 aTPythonDump << "] )";
4929 SMESH_CATCH( SMESH::throwCorbaException );
4932 //=======================================================================
4933 //function : MergeEqualElements
4935 //=======================================================================
4937 void SMESH_MeshEditor_i::MergeEqualElements()
4938 throw (SALOME::SALOME_Exception)
4943 getEditor().MergeEqualElements();
4945 declareMeshModified( /*isReComputeSafe=*/true );
4947 TPythonDump() << this << ".MergeEqualElements()";
4949 SMESH_CATCH( SMESH::throwCorbaException );
4952 //=============================================================================
4954 * Move the node to a given point
4956 //=============================================================================
4958 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4962 throw (SALOME::SALOME_Exception)
4965 initData(/*deleteSearchers=*/false);
4967 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
4971 if ( theNodeSearcher )
4972 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4974 if ( myIsPreviewMode ) // make preview data
4976 // in a preview mesh, make edges linked to a node
4977 TPreviewMesh& tmpMesh = *getPreviewMesh();
4978 TIDSortedElemSet linkedNodes;
4979 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4980 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4981 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4982 for ( ; nIt != linkedNodes.end(); ++nIt )
4984 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4985 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4989 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4990 // fill preview data
4992 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4993 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4995 getMeshDS()->MoveNode(node, x, y, z);
4997 if ( !myIsPreviewMode )
4999 // Update Python script
5000 TPythonDump() << "isDone = " << this << ".MoveNode( "
5001 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
5002 declareMeshModified( /*isReComputeSafe=*/false );
5005 SMESH_CATCH( SMESH::throwCorbaException );
5010 //================================================================================
5012 * \brief Return ID of node closest to a given point
5014 //================================================================================
5016 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
5019 throw (SALOME::SALOME_Exception)
5022 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5024 if ( !theNodeSearcher ) {
5025 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5028 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
5029 return node->GetID();
5031 SMESH_CATCH( SMESH::throwCorbaException );
5035 //================================================================================
5037 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
5038 * move the node closest to the point to point's location and return ID of the node
5040 //================================================================================
5042 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
5045 CORBA::Long theNodeID)
5046 throw (SALOME::SALOME_Exception)
5049 // We keep theNodeSearcher until any mesh modification:
5050 // 1) initData() deletes theNodeSearcher at any edition,
5051 // 2) TSearchersDeleter - at any mesh compute event and mesh change
5053 initData(/*deleteSearchers=*/false);
5055 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5057 int nodeID = theNodeID;
5058 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
5059 if ( !node ) // preview moving node
5061 if ( !theNodeSearcher ) {
5062 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5065 node = theNodeSearcher->FindClosestTo( p );
5068 nodeID = node->GetID();
5069 if ( myIsPreviewMode ) // make preview data
5071 // in a preview mesh, make edges linked to a node
5072 TPreviewMesh tmpMesh = *getPreviewMesh();
5073 TIDSortedElemSet linkedNodes;
5074 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5075 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5076 for ( ; nIt != linkedNodes.end(); ++nIt )
5078 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
5079 tmpMesh.Copy( &edge );
5082 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
5084 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
5085 // fill preview data
5087 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5089 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5093 getMeshDS()->MoveNode(node, x, y, z);
5097 if ( !myIsPreviewMode )
5099 TPythonDump() << "nodeID = " << this
5100 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
5101 << ", " << nodeID << " )";
5103 declareMeshModified( /*isReComputeSafe=*/false );
5108 SMESH_CATCH( SMESH::throwCorbaException );
5112 //=======================================================================
5114 * Return elements of given type where the given point is IN or ON.
5116 * 'ALL' type means elements of any type excluding nodes
5118 //=======================================================================
5120 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
5123 SMESH::ElementType type)
5124 throw (SALOME::SALOME_Exception)
5127 SMESH::long_array_var res = new SMESH::long_array;
5128 vector< const SMDS_MeshElement* > foundElems;
5130 theSearchersDeleter.Set( myMesh );
5131 if ( !theElementSearcher ) {
5132 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5134 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5135 SMDSAbs_ElementType( type ),
5137 res->length( foundElems.size() );
5138 for ( int i = 0; i < foundElems.size(); ++i )
5139 res[i] = foundElems[i]->GetID();
5141 if ( !myIsPreviewMode ) // call from tui
5142 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
5150 SMESH_CATCH( SMESH::throwCorbaException );
5154 //=======================================================================
5155 //function : FindAmongElementsByPoint
5156 //purpose : Searching among the given elements, return elements of given type
5157 // where the given point is IN or ON.
5158 // 'ALL' type means elements of any type excluding nodes
5159 //=======================================================================
5162 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
5166 SMESH::ElementType type)
5167 throw (SALOME::SALOME_Exception)
5170 SMESH::long_array_var res = new SMESH::long_array;
5172 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
5173 if ( types->length() == 1 && // a part contains only nodes or 0D elements
5174 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
5175 type != types[0] ) // but search of elements of dim > 0
5178 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
5179 return FindElementsByPoint( x,y,z, type );
5181 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
5183 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
5184 if ( !theElementSearcher )
5186 // create a searcher from elementIDs
5187 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
5188 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
5190 if ( !idSourceToSet( elementIDs, meshDS, elements,
5191 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
5194 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5195 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
5197 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
5200 vector< const SMDS_MeshElement* > foundElems;
5202 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5203 SMDSAbs_ElementType( type ),
5205 res->length( foundElems.size() );
5206 for ( int i = 0; i < foundElems.size(); ++i )
5207 res[i] = foundElems[i]->GetID();
5209 if ( !myIsPreviewMode ) // call from tui
5210 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
5211 << elementIDs << ", "
5219 SMESH_CATCH( SMESH::throwCorbaException );
5223 //=======================================================================
5224 //function : GetPointState
5225 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
5226 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
5227 //=======================================================================
5229 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
5232 throw (SALOME::SALOME_Exception)
5235 theSearchersDeleter.Set( myMesh );
5236 if ( !theElementSearcher ) {
5237 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5239 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
5241 SMESH_CATCH( SMESH::throwCorbaException );
5245 //=======================================================================
5246 //function : convError
5248 //=======================================================================
5250 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
5252 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
5256 RETCASE( SEW_BORDER1_NOT_FOUND );
5257 RETCASE( SEW_BORDER2_NOT_FOUND );
5258 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
5259 RETCASE( SEW_BAD_SIDE_NODES );
5260 RETCASE( SEW_VOLUMES_TO_SPLIT );
5261 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
5262 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
5263 RETCASE( SEW_BAD_SIDE1_NODES );
5264 RETCASE( SEW_BAD_SIDE2_NODES );
5266 return SMESH::SMESH_MeshEditor::SEW_OK;
5269 //=======================================================================
5270 //function : SewFreeBorders
5272 //=======================================================================
5274 SMESH::SMESH_MeshEditor::Sew_Error
5275 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
5276 CORBA::Long SecondNodeID1,
5277 CORBA::Long LastNodeID1,
5278 CORBA::Long FirstNodeID2,
5279 CORBA::Long SecondNodeID2,
5280 CORBA::Long LastNodeID2,
5281 CORBA::Boolean CreatePolygons,
5282 CORBA::Boolean CreatePolyedrs)
5283 throw (SALOME::SALOME_Exception)
5288 SMESHDS_Mesh* aMesh = getMeshDS();
5290 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5291 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5292 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5293 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5294 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5295 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
5297 if (!aBorderFirstNode ||
5298 !aBorderSecondNode||
5300 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5301 if (!aSide2FirstNode ||
5302 !aSide2SecondNode ||
5304 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5306 TPythonDump() << "error = " << this << ".SewFreeBorders( "
5307 << FirstNodeID1 << ", "
5308 << SecondNodeID1 << ", "
5309 << LastNodeID1 << ", "
5310 << FirstNodeID2 << ", "
5311 << SecondNodeID2 << ", "
5312 << LastNodeID2 << ", "
5313 << CreatePolygons<< ", "
5314 << CreatePolyedrs<< " )";
5316 SMESH::SMESH_MeshEditor::Sew_Error error =
5317 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5328 declareMeshModified( /*isReComputeSafe=*/false );
5331 SMESH_CATCH( SMESH::throwCorbaException );
5332 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5336 //=======================================================================
5337 //function : SewConformFreeBorders
5339 //=======================================================================
5341 SMESH::SMESH_MeshEditor::Sew_Error
5342 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
5343 CORBA::Long SecondNodeID1,
5344 CORBA::Long LastNodeID1,
5345 CORBA::Long FirstNodeID2,
5346 CORBA::Long SecondNodeID2)
5347 throw (SALOME::SALOME_Exception)
5352 SMESHDS_Mesh* aMesh = getMeshDS();
5354 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5355 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5356 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5357 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5358 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5359 const SMDS_MeshNode* aSide2ThirdNode = 0;
5361 if (!aBorderFirstNode ||
5362 !aBorderSecondNode||
5364 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5365 if (!aSide2FirstNode ||
5367 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5369 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
5370 << FirstNodeID1 << ", "
5371 << SecondNodeID1 << ", "
5372 << LastNodeID1 << ", "
5373 << FirstNodeID2 << ", "
5374 << SecondNodeID2 << " )";
5376 SMESH::SMESH_MeshEditor::Sew_Error error =
5377 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5386 declareMeshModified( /*isReComputeSafe=*/false );
5389 SMESH_CATCH( SMESH::throwCorbaException );
5390 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5394 //=======================================================================
5395 //function : SewBorderToSide
5397 //=======================================================================
5399 SMESH::SMESH_MeshEditor::Sew_Error
5400 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5401 CORBA::Long SecondNodeIDOnFreeBorder,
5402 CORBA::Long LastNodeIDOnFreeBorder,
5403 CORBA::Long FirstNodeIDOnSide,
5404 CORBA::Long LastNodeIDOnSide,
5405 CORBA::Boolean CreatePolygons,
5406 CORBA::Boolean CreatePolyedrs)
5407 throw (SALOME::SALOME_Exception)
5412 SMESHDS_Mesh* aMesh = getMeshDS();
5414 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5415 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5416 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5417 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5418 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5419 const SMDS_MeshNode* aSide2ThirdNode = 0;
5421 if (!aBorderFirstNode ||
5422 !aBorderSecondNode||
5424 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5425 if (!aSide2FirstNode ||
5427 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5429 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5430 << FirstNodeIDOnFreeBorder << ", "
5431 << SecondNodeIDOnFreeBorder << ", "
5432 << LastNodeIDOnFreeBorder << ", "
5433 << FirstNodeIDOnSide << ", "
5434 << LastNodeIDOnSide << ", "
5435 << CreatePolygons << ", "
5436 << CreatePolyedrs << ") ";
5438 SMESH::SMESH_MeshEditor::Sew_Error error =
5439 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5449 declareMeshModified( /*isReComputeSafe=*/false );
5452 SMESH_CATCH( SMESH::throwCorbaException );
5453 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5457 //=======================================================================
5458 //function : SewSideElements
5460 //=======================================================================
5462 SMESH::SMESH_MeshEditor::Sew_Error
5463 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5464 const SMESH::long_array& IDsOfSide2Elements,
5465 CORBA::Long NodeID1OfSide1ToMerge,
5466 CORBA::Long NodeID1OfSide2ToMerge,
5467 CORBA::Long NodeID2OfSide1ToMerge,
5468 CORBA::Long NodeID2OfSide2ToMerge)
5469 throw (SALOME::SALOME_Exception)
5474 SMESHDS_Mesh* aMesh = getMeshDS();
5476 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5477 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5478 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5479 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5481 if (!aFirstNode1ToMerge ||
5482 !aFirstNode2ToMerge )
5483 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5484 if (!aSecondNode1ToMerge||
5485 !aSecondNode2ToMerge)
5486 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5488 TIDSortedElemSet aSide1Elems, aSide2Elems;
5489 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5490 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5492 TPythonDump() << "error = " << this << ".SewSideElements( "
5493 << IDsOfSide1Elements << ", "
5494 << IDsOfSide2Elements << ", "
5495 << NodeID1OfSide1ToMerge << ", "
5496 << NodeID1OfSide2ToMerge << ", "
5497 << NodeID2OfSide1ToMerge << ", "
5498 << NodeID2OfSide2ToMerge << ")";
5500 SMESH::SMESH_MeshEditor::Sew_Error error =
5501 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5504 aSecondNode1ToMerge,
5505 aSecondNode2ToMerge));
5507 declareMeshModified( /*isReComputeSafe=*/false );
5510 SMESH_CATCH( SMESH::throwCorbaException );
5511 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5514 //================================================================================
5516 * \brief Set new nodes for given element
5517 * \param ide - element id
5518 * \param newIDs - new node ids
5519 * \retval CORBA::Boolean - true if result is OK
5521 //================================================================================
5523 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5524 const SMESH::long_array& newIDs)
5525 throw (SALOME::SALOME_Exception)
5530 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5531 if(!elem) return false;
5533 int nbn = newIDs.length();
5535 vector<const SMDS_MeshNode*> aNodes(nbn);
5538 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5541 aNodes[nbn1] = aNode;
5544 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5545 << ide << ", " << newIDs << " )";
5547 MESSAGE("ChangeElementNodes");
5548 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5550 declareMeshModified( /*isReComputeSafe=*/ !res );
5554 SMESH_CATCH( SMESH::throwCorbaException );
5558 //=======================================================================
5560 * \brief Makes a part of the mesh quadratic or bi-quadratic
5562 //=======================================================================
5564 void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d,
5565 CORBA::Boolean theToBiQuad,
5566 SMESH::SMESH_IDSource_ptr theObject)
5567 throw (SALOME::SALOME_Exception)
5570 TIDSortedElemSet elems;
5572 if ( !( elemsOK = CORBA::is_nil( theObject )))
5574 prepareIdSource( theObject );
5575 elemsOK = idSourceToSet( theObject, getMeshDS(), elems,
5576 SMDSAbs_All, /*emptyIfIsMesh=*/true );
5580 if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
5581 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5583 if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
5584 else getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
5586 declareMeshModified( /*isReComputeSafe=*/false );
5589 SMESH_CATCH( SMESH::throwCorbaException );
5592 //=======================================================================
5593 //function : ConvertFromQuadratic
5595 //=======================================================================
5597 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5598 throw (SALOME::SALOME_Exception)
5600 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5601 TPythonDump() << this << ".ConvertFromQuadratic()";
5602 declareMeshModified( /*isReComputeSafe=*/!isDone );
5606 //=======================================================================
5607 //function : ConvertToQuadratic
5609 //=======================================================================
5611 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5612 throw (SALOME::SALOME_Exception)
5614 convertToQuadratic( theForce3d, false );
5615 TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
5618 //================================================================================
5620 * \brief Makes a part of the mesh quadratic
5622 //================================================================================
5624 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5625 SMESH::SMESH_IDSource_ptr theObject)
5626 throw (SALOME::SALOME_Exception)
5628 convertToQuadratic( theForce3d, false, theObject );
5629 TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
5632 //================================================================================
5634 * \brief Makes a part of the mesh bi-quadratic
5636 //================================================================================
5638 void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean theForce3d,
5639 SMESH::SMESH_IDSource_ptr theObject)
5640 throw (SALOME::SALOME_Exception)
5642 convertToQuadratic( theForce3d, true, theObject );
5643 TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
5646 //================================================================================
5648 * \brief Makes a part of the mesh linear
5650 //================================================================================
5652 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5653 throw (SALOME::SALOME_Exception)
5659 TIDSortedElemSet elems;
5660 prepareIdSource( theObject );
5661 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5663 if ( elems.empty() )
5665 ConvertFromQuadratic();
5667 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5669 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5673 getEditor().ConvertFromQuadratic(elems);
5676 declareMeshModified( /*isReComputeSafe=*/false );
5678 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5680 SMESH_CATCH( SMESH::throwCorbaException );
5683 //=======================================================================
5684 //function : makeMesh
5685 //purpose : create a named imported mesh
5686 //=======================================================================
5688 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5690 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5691 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5692 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5693 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5694 gen->SetName( meshSO, theMeshName, "Mesh" );
5695 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5697 return mesh._retn();
5700 //=======================================================================
5701 //function : dumpGroupsList
5703 //=======================================================================
5705 void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPython,
5706 const SMESH::ListOfGroups * theGroupList)
5708 bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
5709 if ( isDumpGroupList )
5710 theDumpPython << theGroupList << " = ";
5713 //================================================================================
5715 \brief Generates the unique group name.
5716 \param thePrefix name prefix
5719 //================================================================================
5721 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5723 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5724 set<string> groupNames;
5726 // Get existing group names
5727 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5728 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5729 if (CORBA::is_nil(aGroup))
5732 CORBA::String_var name = aGroup->GetName();
5733 groupNames.insert( name.in() );
5737 string name = thePrefix;
5740 while (!groupNames.insert(name).second)
5741 name = SMESH_Comment( thePrefix ) << "_" << index++;
5746 //================================================================================
5748 * \brief Prepare SMESH_IDSource for work
5750 //================================================================================
5752 void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
5754 if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5756 SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
5757 filter->SetMesh( mesh );
5761 //================================================================================
5763 * \brief Duplicates given elements, i.e. creates new elements based on the
5764 * same nodes as the given ones.
5765 * \param theElements - container of elements to duplicate.
5766 * \param theGroupName - a name of group to contain the generated elements.
5767 * If a group with such a name already exists, the new elements
5768 * are added to the existng group, else a new group is created.
5769 * If \a theGroupName is empty, new elements are not added
5771 * \return a group where the new elements are added. NULL if theGroupName == "".
5774 //================================================================================
5776 SMESH::SMESH_Group_ptr
5777 SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
5778 const char* theGroupName)
5779 throw (SALOME::SALOME_Exception)
5781 SMESH::SMESH_Group_var newGroup;
5788 TIDSortedElemSet elems;
5789 prepareIdSource( theElements );
5790 if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
5792 getEditor().DoubleElements( elems );
5794 if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
5797 SMESH::ElementType type =
5798 SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
5799 // find existing group
5800 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5801 for ( size_t i = 0; i < groups->length(); ++i )
5802 if ( groups[i]->GetType() == type )
5804 CORBA::String_var name = groups[i]->GetName();
5805 if ( strcmp( name, theGroupName ) == 0 ) {
5806 newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
5810 // create a new group
5811 if ( newGroup->_is_nil() )
5812 newGroup = myMesh_i->CreateGroup( type, theGroupName );
5814 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
5816 SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
5817 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
5818 for ( int i = 1; i <= aSeq.Length(); i++ )
5819 groupDS->SMDSGroup().Add( aSeq(i) );
5824 if ( !newGroup->_is_nil() )
5825 pyDump << newGroup << " = ";
5826 pyDump << this << ".DoubleElements( "
5827 << theElements << ", " << "'" << theGroupName <<"')";
5829 SMESH_CATCH( SMESH::throwCorbaException );
5831 return newGroup._retn();
5834 //================================================================================
5836 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5837 \param theNodes - identifiers of nodes to be doubled
5838 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5839 nodes. If list of element identifiers is empty then nodes are doubled but
5840 they not assigned to elements
5841 \return TRUE if operation has been completed successfully, FALSE otherwise
5842 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5844 //================================================================================
5846 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5847 const SMESH::long_array& theModifiedElems )
5848 throw (SALOME::SALOME_Exception)
5853 list< int > aListOfNodes;
5855 for ( i = 0, n = theNodes.length(); i < n; i++ )
5856 aListOfNodes.push_back( theNodes[ i ] );
5858 list< int > aListOfElems;
5859 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5860 aListOfElems.push_back( theModifiedElems[ i ] );
5862 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
5864 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5866 // Update Python script
5867 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5871 SMESH_CATCH( SMESH::throwCorbaException );
5875 //================================================================================
5877 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5878 This method provided for convenience works as DoubleNodes() described above.
5879 \param theNodeId - identifier of node to be doubled.
5880 \param theModifiedElems - identifiers of elements to be updated.
5881 \return TRUE if operation has been completed successfully, FALSE otherwise
5882 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5884 //================================================================================
5886 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5887 const SMESH::long_array& theModifiedElems )
5888 throw (SALOME::SALOME_Exception)
5891 SMESH::long_array_var aNodes = new SMESH::long_array;
5892 aNodes->length( 1 );
5893 aNodes[ 0 ] = theNodeId;
5895 TPythonDump pyDump; // suppress dump by the next line
5897 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5899 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5903 SMESH_CATCH( SMESH::throwCorbaException );
5907 //================================================================================
5909 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5910 This method provided for convenience works as DoubleNodes() described above.
5911 \param theNodes - group of nodes to be doubled.
5912 \param theModifiedElems - group of elements to be updated.
5913 \return TRUE if operation has been completed successfully, FALSE otherwise
5914 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5916 //================================================================================
5918 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5919 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5920 throw (SALOME::SALOME_Exception)
5923 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5926 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5927 SMESH::long_array_var aModifiedElems;
5928 if ( !CORBA::is_nil( theModifiedElems ) )
5929 aModifiedElems = theModifiedElems->GetListOfID();
5932 aModifiedElems = new SMESH::long_array;
5933 aModifiedElems->length( 0 );
5936 TPythonDump pyDump; // suppress dump by the next line
5938 bool done = DoubleNodes( aNodes, aModifiedElems );
5940 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5944 SMESH_CATCH( SMESH::throwCorbaException );
5948 //================================================================================
5950 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5951 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5952 * \param theNodes - group of nodes to be doubled.
5953 * \param theModifiedElems - group of elements to be updated.
5954 * \return a new group with newly created nodes
5955 * \sa DoubleNodeGroup()
5957 //================================================================================
5959 SMESH::SMESH_Group_ptr
5960 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5961 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5962 throw (SALOME::SALOME_Exception)
5965 SMESH::SMESH_Group_var aNewGroup;
5967 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5968 return aNewGroup._retn();
5971 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5972 SMESH::long_array_var aModifiedElems;
5973 if ( !CORBA::is_nil( theModifiedElems ) )
5974 aModifiedElems = theModifiedElems->GetListOfID();
5976 aModifiedElems = new SMESH::long_array;
5977 aModifiedElems->length( 0 );
5980 TPythonDump pyDump; // suppress dump by the next line
5982 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5985 // Create group with newly created nodes
5986 SMESH::long_array_var anIds = GetLastCreatedNodes();
5987 if (anIds->length() > 0) {
5988 string anUnindexedName (theNodes->GetName());
5989 string aNewName = generateGroupName(anUnindexedName + "_double");
5990 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5991 aNewGroup->Add(anIds);
5992 pyDump << aNewGroup << " = ";
5996 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5997 << theModifiedElems << " )";
5999 return aNewGroup._retn();
6001 SMESH_CATCH( SMESH::throwCorbaException );
6005 //================================================================================
6007 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6008 This method provided for convenience works as DoubleNodes() described above.
6009 \param theNodes - list of groups of nodes to be doubled
6010 \param theModifiedElems - list of groups of elements to be updated.
6011 \return TRUE if operation has been completed successfully, FALSE otherwise
6012 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
6014 //================================================================================
6016 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
6017 const SMESH::ListOfGroups& theModifiedElems )
6018 throw (SALOME::SALOME_Exception)
6023 std::list< int > aNodes;
6025 for ( i = 0, n = theNodes.length(); i < n; i++ )
6027 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
6028 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
6030 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6031 for ( j = 0, m = aCurr->length(); j < m; j++ )
6032 aNodes.push_back( aCurr[ j ] );
6036 std::list< int > anElems;
6037 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
6039 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
6040 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
6042 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6043 for ( j = 0, m = aCurr->length(); j < m; j++ )
6044 anElems.push_back( aCurr[ j ] );
6048 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
6050 declareMeshModified( /*isReComputeSafe=*/false );
6052 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
6056 SMESH_CATCH( SMESH::throwCorbaException );
6060 //================================================================================
6062 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6063 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
6064 * \param theNodes - group of nodes to be doubled.
6065 * \param theModifiedElems - group of elements to be updated.
6066 * \return a new group with newly created nodes
6067 * \sa DoubleNodeGroups()
6069 //================================================================================
6071 SMESH::SMESH_Group_ptr
6072 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
6073 const SMESH::ListOfGroups& theModifiedElems )
6074 throw (SALOME::SALOME_Exception)
6076 SMESH::SMESH_Group_var aNewGroup;
6078 TPythonDump pyDump; // suppress dump by the next line
6080 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
6084 // Create group with newly created nodes
6085 SMESH::long_array_var anIds = GetLastCreatedNodes();
6086 if (anIds->length() > 0) {
6087 string anUnindexedName (theNodes[0]->GetName());
6088 string aNewName = generateGroupName(anUnindexedName + "_double");
6089 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6090 aNewGroup->Add(anIds);
6091 pyDump << aNewGroup << " = ";
6095 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
6096 << theModifiedElems << " )";
6098 return aNewGroup._retn();
6102 //================================================================================
6104 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6105 \param theElems - the list of elements (edges or faces) to be replicated
6106 The nodes for duplication could be found from these elements
6107 \param theNodesNot - list of nodes to NOT replicate
6108 \param theAffectedElems - the list of elements (cells and edges) to which the
6109 replicated nodes should be associated to.
6110 \return TRUE if operation has been completed successfully, FALSE otherwise
6111 \sa DoubleNodeGroup(), DoubleNodeGroups()
6113 //================================================================================
6115 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
6116 const SMESH::long_array& theNodesNot,
6117 const SMESH::long_array& theAffectedElems )
6118 throw (SALOME::SALOME_Exception)
6123 SMESHDS_Mesh* aMeshDS = getMeshDS();
6124 TIDSortedElemSet anElems, aNodes, anAffected;
6125 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6126 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6127 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
6129 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6131 // Update Python script
6132 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
6133 << theNodesNot << ", " << theAffectedElems << " )";
6135 declareMeshModified( /*isReComputeSafe=*/false );
6138 SMESH_CATCH( SMESH::throwCorbaException );
6142 //================================================================================
6144 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6145 \param theElems - the list of elements (edges or faces) to be replicated
6146 The nodes for duplication could be found from these elements
6147 \param theNodesNot - list of nodes to NOT replicate
6148 \param theShape - shape to detect affected elements (element which geometric center
6149 located on or inside shape).
6150 The replicated nodes should be associated to affected elements.
6151 \return TRUE if operation has been completed successfully, FALSE otherwise
6152 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
6154 //================================================================================
6156 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
6157 const SMESH::long_array& theNodesNot,
6158 GEOM::GEOM_Object_ptr theShape )
6159 throw (SALOME::SALOME_Exception)
6165 SMESHDS_Mesh* aMeshDS = getMeshDS();
6166 TIDSortedElemSet anElems, aNodes;
6167 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6168 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6170 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6171 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6173 // Update Python script
6174 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
6175 << theNodesNot << ", " << theShape << " )";
6177 declareMeshModified( /*isReComputeSafe=*/false );
6180 SMESH_CATCH( SMESH::throwCorbaException );
6184 //================================================================================
6186 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6187 \param theElems - group of of elements (edges or faces) to be replicated
6188 \param theNodesNot - group of nodes not to replicated
6189 \param theAffectedElems - group of elements to which the replicated nodes
6190 should be associated to.
6191 \return TRUE if operation has been completed successfully, FALSE otherwise
6192 \sa DoubleNodes(), DoubleNodeGroups()
6194 //================================================================================
6197 SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
6198 SMESH::SMESH_GroupBase_ptr theNodesNot,
6199 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6200 throw (SALOME::SALOME_Exception)
6203 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6209 SMESHDS_Mesh* aMeshDS = getMeshDS();
6210 TIDSortedElemSet anElems, aNodes, anAffected;
6211 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6212 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6213 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6215 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6217 // Update Python script
6218 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
6219 << theNodesNot << ", " << theAffectedElems << " )";
6221 declareMeshModified( /*isReComputeSafe=*/false );
6224 SMESH_CATCH( SMESH::throwCorbaException );
6228 //================================================================================
6230 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6231 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6232 * \param theElems - group of of elements (edges or faces) to be replicated
6233 * \param theNodesNot - group of nodes not to replicated
6234 * \param theAffectedElems - group of elements to which the replicated nodes
6235 * should be associated to.
6236 * \return a new group with newly created elements
6237 * \sa DoubleNodeElemGroup()
6239 //================================================================================
6241 SMESH::SMESH_Group_ptr
6242 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
6243 SMESH::SMESH_GroupBase_ptr theNodesNot,
6244 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6245 throw (SALOME::SALOME_Exception)
6248 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
6252 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6253 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6255 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
6257 << theNodesNot << ", "
6258 << theAffectedElems << " )";
6260 return elemGroup._retn();
6263 //================================================================================
6265 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6266 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6267 * \param theElems - group of of elements (edges or faces) to be replicated
6268 * \param theNodesNot - group of nodes not to replicated
6269 * \param theAffectedElems - group of elements to which the replicated nodes
6270 * should be associated to.
6271 * \return a new group with newly created elements
6272 * \sa DoubleNodeElemGroup()
6274 //================================================================================
6276 SMESH::ListOfGroups*
6277 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
6278 SMESH::SMESH_GroupBase_ptr theNodesNot,
6279 SMESH::SMESH_GroupBase_ptr theAffectedElems,
6280 CORBA::Boolean theElemGroupNeeded,
6281 CORBA::Boolean theNodeGroupNeeded)
6282 throw (SALOME::SALOME_Exception)
6285 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6286 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6287 aTwoGroups->length( 2 );
6289 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6290 return aTwoGroups._retn();
6295 SMESHDS_Mesh* aMeshDS = getMeshDS();
6296 TIDSortedElemSet anElems, aNodes, anAffected;
6297 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6298 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6299 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6302 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6304 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6310 // Create group with newly created elements
6311 CORBA::String_var elemGroupName = theElems->GetName();
6312 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6313 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6315 SMESH::long_array_var anIds = GetLastCreatedElems();
6316 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6317 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6318 aNewElemGroup->Add(anIds);
6320 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6322 SMESH::long_array_var anIds = GetLastCreatedNodes();
6323 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6324 aNewNodeGroup->Add(anIds);
6328 // Update Python script
6331 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6332 else pyDump << aNewElemGroup << ", ";
6333 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6334 else pyDump << aNewNodeGroup << " ] = ";
6336 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
6337 << theNodesNot << ", "
6338 << theAffectedElems << ", "
6339 << theElemGroupNeeded << ", "
6340 << theNodeGroupNeeded <<" )";
6342 aTwoGroups[0] = aNewElemGroup._retn();
6343 aTwoGroups[1] = aNewNodeGroup._retn();
6344 return aTwoGroups._retn();
6346 SMESH_CATCH( SMESH::throwCorbaException );
6350 //================================================================================
6352 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6353 \param theElems - group of of elements (edges or faces) to be replicated
6354 \param theNodesNot - group of nodes not to replicated
6355 \param theShape - shape to detect affected elements (element which geometric center
6356 located on or inside shape).
6357 The replicated nodes should be associated to affected elements.
6358 \return TRUE if operation has been completed successfully, FALSE otherwise
6359 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
6361 //================================================================================
6364 SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
6365 SMESH::SMESH_GroupBase_ptr theNodesNot,
6366 GEOM::GEOM_Object_ptr theShape )
6367 throw (SALOME::SALOME_Exception)
6370 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6376 SMESHDS_Mesh* aMeshDS = getMeshDS();
6377 TIDSortedElemSet anElems, aNodes, anAffected;
6378 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6379 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6381 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6382 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6385 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6387 // Update Python script
6388 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
6389 << theNodesNot << ", " << theShape << " )";
6392 SMESH_CATCH( SMESH::throwCorbaException );
6396 //================================================================================
6398 * \brief Re-load elements from a list of groups into a TIDSortedElemSet
6399 * \param [in] theGrpList - groups
6400 * \param [in] theMeshDS - mesh
6401 * \param [out] theElemSet - set of elements
6402 * \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
6404 //================================================================================
6406 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
6407 SMESHDS_Mesh* theMeshDS,
6408 TIDSortedElemSet& theElemSet,
6409 const bool theIsNodeGrp)
6411 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
6413 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
6414 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
6415 : aGrp->GetType() != SMESH::NODE ) )
6417 SMESH::long_array_var anIDs = aGrp->GetIDs();
6418 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
6423 //================================================================================
6425 \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6426 This method provided for convenience works as DoubleNodes() described above.
6427 \param theElems - list of groups of elements (edges or faces) to be replicated
6428 \param theNodesNot - list of groups of nodes not to replicated
6429 \param theAffectedElems - group of elements to which the replicated nodes
6430 should be associated to.
6431 \return TRUE if operation has been completed successfully, FALSE otherwise
6432 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
6434 //================================================================================
6437 SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
6438 const SMESH::ListOfGroups& theNodesNot,
6439 const SMESH::ListOfGroups& theAffectedElems)
6440 throw (SALOME::SALOME_Exception)
6446 SMESHDS_Mesh* aMeshDS = getMeshDS();
6447 TIDSortedElemSet anElems, aNodes, anAffected;
6448 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6449 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6450 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6452 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6454 // Update Python script
6455 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
6456 << &theNodesNot << ", " << &theAffectedElems << " )";
6458 declareMeshModified( /*isReComputeSafe=*/false );
6461 SMESH_CATCH( SMESH::throwCorbaException );
6465 //================================================================================
6467 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6468 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6469 \param theElems - list of groups of elements (edges or faces) to be replicated
6470 \param theNodesNot - list of groups of nodes not to replicated
6471 \param theAffectedElems - group of elements to which the replicated nodes
6472 should be associated to.
6473 * \return a new group with newly created elements
6474 * \sa DoubleNodeElemGroups()
6476 //================================================================================
6478 SMESH::SMESH_Group_ptr
6479 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
6480 const SMESH::ListOfGroups& theNodesNot,
6481 const SMESH::ListOfGroups& theAffectedElems)
6482 throw (SALOME::SALOME_Exception)
6485 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
6489 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6490 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6492 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
6494 << theNodesNot << ", "
6495 << theAffectedElems << " )";
6497 return elemGroup._retn();
6500 //================================================================================
6502 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6503 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6504 \param theElems - list of groups of elements (edges or faces) to be replicated
6505 \param theNodesNot - list of groups of nodes not to replicated
6506 \param theAffectedElems - group of elements to which the replicated nodes
6507 should be associated to.
6508 * \return a new group with newly created elements
6509 * \sa DoubleNodeElemGroups()
6511 //================================================================================
6513 SMESH::ListOfGroups*
6514 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
6515 const SMESH::ListOfGroups& theNodesNot,
6516 const SMESH::ListOfGroups& theAffectedElems,
6517 CORBA::Boolean theElemGroupNeeded,
6518 CORBA::Boolean theNodeGroupNeeded)
6519 throw (SALOME::SALOME_Exception)
6522 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6523 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6524 aTwoGroups->length( 2 );
6529 SMESHDS_Mesh* aMeshDS = getMeshDS();
6530 TIDSortedElemSet anElems, aNodes, anAffected;
6531 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6532 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6533 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6535 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6537 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6542 // Create group with newly created elements
6543 CORBA::String_var elemGroupName = theElems[0]->GetName();
6544 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6545 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6547 SMESH::long_array_var anIds = GetLastCreatedElems();
6548 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6549 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6550 aNewElemGroup->Add(anIds);
6552 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6554 SMESH::long_array_var anIds = GetLastCreatedNodes();
6555 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6556 aNewNodeGroup->Add(anIds);
6560 // Update Python script
6563 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6564 else pyDump << aNewElemGroup << ", ";
6565 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6566 else pyDump << aNewNodeGroup << " ] = ";
6568 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6569 << &theNodesNot << ", "
6570 << &theAffectedElems << ", "
6571 << theElemGroupNeeded << ", "
6572 << theNodeGroupNeeded << " )";
6574 aTwoGroups[0] = aNewElemGroup._retn();
6575 aTwoGroups[1] = aNewNodeGroup._retn();
6576 return aTwoGroups._retn();
6578 SMESH_CATCH( SMESH::throwCorbaException );
6582 //================================================================================
6584 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6585 This method provided for convenience works as DoubleNodes() described above.
6586 \param theElems - list of groups of elements (edges or faces) to be replicated
6587 \param theNodesNot - list of groups of nodes not to replicated
6588 \param theShape - shape to detect affected elements (element which geometric center
6589 located on or inside shape).
6590 The replicated nodes should be associated to affected elements.
6591 \return TRUE if operation has been completed successfully, FALSE otherwise
6592 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6594 //================================================================================
6597 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6598 const SMESH::ListOfGroups& theNodesNot,
6599 GEOM::GEOM_Object_ptr theShape )
6600 throw (SALOME::SALOME_Exception)
6606 SMESHDS_Mesh* aMeshDS = getMeshDS();
6607 TIDSortedElemSet anElems, aNodes;
6608 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6609 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6611 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6612 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6614 // Update Python script
6615 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6616 << &theNodesNot << ", " << theShape << " )";
6618 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6621 SMESH_CATCH( SMESH::throwCorbaException );
6625 //================================================================================
6627 \brief Identify the elements that will be affected by node duplication (actual
6628 duplication is not performed.
6629 This method is the first step of DoubleNodeElemGroupsInRegion.
6630 \param theElems - list of groups of elements (edges or faces) to be replicated
6631 \param theNodesNot - list of groups of nodes not to replicated
6632 \param theShape - shape to detect affected elements (element which geometric center
6633 located on or inside shape).
6634 The replicated nodes should be associated to affected elements.
6635 \return groups of affected elements
6636 \sa DoubleNodeElemGroupsInRegion()
6638 //================================================================================
6639 SMESH::ListOfGroups*
6640 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6641 const SMESH::ListOfGroups& theNodesNot,
6642 GEOM::GEOM_Object_ptr theShape )
6643 throw (SALOME::SALOME_Exception)
6646 MESSAGE("AffectedElemGroupsInRegion");
6647 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6648 bool isEdgeGroup = false;
6649 bool isFaceGroup = false;
6650 bool isVolumeGroup = false;
6651 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6652 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6653 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6657 ::SMESH_MeshEditor aMeshEditor(myMesh);
6659 SMESHDS_Mesh* aMeshDS = getMeshDS();
6660 TIDSortedElemSet anElems, aNodes;
6661 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6662 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6664 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6665 TIDSortedElemSet anAffected;
6666 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6669 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6674 int lg = anAffected.size();
6675 MESSAGE("lg="<< lg);
6676 SMESH::long_array_var volumeIds = new SMESH::long_array;
6677 volumeIds->length(lg);
6678 SMESH::long_array_var faceIds = new SMESH::long_array;
6679 faceIds->length(lg);
6680 SMESH::long_array_var edgeIds = new SMESH::long_array;
6681 edgeIds->length(lg);
6686 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6687 for (; eIt != anAffected.end(); ++eIt)
6689 const SMDS_MeshElement* anElem = *eIt;
6692 int elemId = anElem->GetID();
6693 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6694 volumeIds[ivol++] = elemId;
6695 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6696 faceIds[iface++] = elemId;
6697 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6698 edgeIds[iedge++] = elemId;
6700 volumeIds->length(ivol);
6701 faceIds->length(iface);
6702 edgeIds->length(iedge);
6704 aNewVolumeGroup->Add(volumeIds);
6705 aNewFaceGroup->Add(faceIds);
6706 aNewEdgeGroup->Add(edgeIds);
6707 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6708 isFaceGroup = (aNewFaceGroup->Size() > 0);
6709 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6713 if (isEdgeGroup) nbGroups++;
6714 if (isFaceGroup) nbGroups++;
6715 if (isVolumeGroup) nbGroups++;
6716 aListOfGroups->length(nbGroups);
6719 if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
6720 if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
6721 if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
6723 // Update Python script
6726 if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
6727 if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
6728 if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
6730 pyDump << this << ".AffectedElemGroupsInRegion( "
6731 << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6733 return aListOfGroups._retn();
6735 SMESH_CATCH( SMESH::throwCorbaException );
6739 //================================================================================
6741 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6742 The created 2D mesh elements based on nodes of free faces of boundary volumes
6743 \return TRUE if operation has been completed successfully, FALSE otherwise
6745 //================================================================================
6747 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6748 throw (SALOME::SALOME_Exception)
6753 bool aResult = getEditor().Make2DMeshFrom3D();
6755 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6757 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6760 SMESH_CATCH( SMESH::throwCorbaException );
6764 //================================================================================
6766 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6767 * The list of groups must contain at least two groups. The groups have to be disjoint:
6768 * no common element into two different groups.
6769 * The nodes of the internal faces at the boundaries of the groups are doubled.
6770 * Optionally, the internal faces are replaced by flat elements.
6771 * Triangles are transformed into prisms, and quadrangles into hexahedrons.
6772 * The flat elements are stored in groups of volumes.
6773 * These groups are named according to the position of the group in the list:
6774 * 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.
6775 * 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.
6776 * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
6777 * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
6778 * @param theDomains - list of groups of volumes
6779 * @param createJointElems - if TRUE, create the elements
6780 * @return TRUE if operation has been completed successfully, FALSE otherwise
6782 //================================================================================
6785 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6786 CORBA::Boolean createJointElems )
6787 throw (SALOME::SALOME_Exception)
6789 bool aResult = false;
6794 SMESHDS_Mesh* aMeshDS = getMeshDS();
6796 // MESSAGE("theDomains.length = "<<theDomains.length());
6797 if ( theDomains.length() <= 1 )
6798 THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
6799 vector<TIDSortedElemSet> domains;
6802 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6804 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6805 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6807 // if ( aGrp->GetType() != SMESH::VOLUME )
6808 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6809 TIDSortedElemSet domain;
6811 domains.push_back(domain);
6812 SMESH::long_array_var anIDs = aGrp->GetIDs();
6813 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6817 aResult = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems );
6818 // TODO publish the groups of flat elements in study
6820 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6822 // Update Python script
6823 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6824 << ", " << createJointElems << " )";
6826 SMESH_CATCH( SMESH::throwCorbaException );
6831 //================================================================================
6833 * \brief Double nodes on some external faces and create flat elements.
6834 * Flat elements are mainly used by some types of mechanic calculations.
6836 * Each group of the list must be constituted of faces.
6837 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6838 * @param theGroupsOfFaces - list of groups of faces
6839 * @return TRUE if operation has been completed successfully, FALSE otherwise
6841 //================================================================================
6844 SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6845 throw (SALOME::SALOME_Exception)
6850 SMESHDS_Mesh* aMeshDS = getMeshDS();
6852 vector<TIDSortedElemSet> faceGroups;
6855 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6857 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6858 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6860 TIDSortedElemSet faceGroup;
6862 faceGroups.push_back(faceGroup);
6863 SMESH::long_array_var anIDs = aGrp->GetIDs();
6864 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6868 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
6869 // TODO publish the groups of flat elements in study
6871 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6873 // Update Python script
6874 TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6877 SMESH_CATCH( SMESH::throwCorbaException );
6881 //================================================================================
6883 * \brief Identify all the elements around a geom shape, get the faces delimiting
6886 * Build groups of volume to remove, groups of faces to replace on the skin of the
6887 * object, groups of faces to remove inside the object, (idem edges).
6888 * Build ordered list of nodes at the border of each group of faces to replace
6889 * (to be used to build a geom subshape).
6891 //================================================================================
6893 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6894 GEOM::GEOM_Object_ptr theShape,
6895 const char* groupName,
6896 const SMESH::double_array& theNodesCoords,
6897 SMESH::array_of_long_array_out GroupsOfNodes)
6898 throw (SALOME::SALOME_Exception)
6903 std::vector<std::vector<int> > aListOfListOfNodes;
6904 ::SMESH_MeshEditor aMeshEditor( myMesh );
6906 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
6907 if ( !theNodeSearcher )
6908 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
6910 vector<double> nodesCoords;
6911 for (int i = 0; i < theNodesCoords.length(); i++)
6913 nodesCoords.push_back( theNodesCoords[i] );
6916 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6917 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
6918 nodesCoords, aListOfListOfNodes);
6920 GroupsOfNodes = new SMESH::array_of_long_array;
6921 GroupsOfNodes->length( aListOfListOfNodes.size() );
6922 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
6923 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
6925 vector<int>& aListOfNodes = *llIt;
6926 vector<int>::iterator lIt = aListOfNodes.begin();;
6927 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
6928 aGroup.length( aListOfNodes.size() );
6929 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
6930 aGroup[ j ] = (*lIt);
6932 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
6935 << ", '" << groupName << "', "
6936 << theNodesCoords << " )";
6938 SMESH_CATCH( SMESH::throwCorbaException );
6941 // issue 20749 ===================================================================
6943 * \brief Creates missing boundary elements
6944 * \param elements - elements whose boundary is to be checked
6945 * \param dimension - defines type of boundary elements to create
6946 * \param groupName - a name of group to store created boundary elements in,
6947 * "" means not to create the group
6948 * \param meshName - a name of new mesh to store created boundary elements in,
6949 * "" means not to create the new mesh
6950 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
6951 * \param toCopyExistingBondary - if true, not only new but also pre-existing
6952 * boundary elements will be copied into the new mesh
6953 * \param group - returns the create group, if any
6954 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
6956 // ================================================================================
6958 SMESH::SMESH_Mesh_ptr
6959 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
6960 SMESH::Bnd_Dimension dim,
6961 const char* groupName,
6962 const char* meshName,
6963 CORBA::Boolean toCopyElements,
6964 CORBA::Boolean toCopyExistingBondary,
6965 SMESH::SMESH_Group_out group)
6966 throw (SALOME::SALOME_Exception)
6971 if ( dim > SMESH::BND_1DFROM2D )
6972 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6974 SMESHDS_Mesh* aMeshDS = getMeshDS();
6976 SMESH::SMESH_Mesh_var mesh_var;
6977 SMESH::SMESH_Group_var group_var;
6981 TIDSortedElemSet elements;
6982 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
6983 prepareIdSource( idSource );
6984 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
6988 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
6989 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6991 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
6993 // group of new boundary elements
6994 SMESH_Group* smesh_group = 0;
6995 if ( strlen(groupName) )
6997 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
6998 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6999 smesh_group = group_i->GetSmeshGroup();
7003 getEditor().MakeBoundaryMesh( elements,
7004 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7008 toCopyExistingBondary);
7011 smesh_mesh->GetMeshDS()->Modified();
7014 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7016 // result of MakeBoundaryMesh() is a tuple (mesh, group)
7017 if ( mesh_var->_is_nil() )
7018 pyDump << myMesh_i->_this() << ", ";
7020 pyDump << mesh_var << ", ";
7021 if ( group_var->_is_nil() )
7022 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7024 pyDump << group_var << " = ";
7025 pyDump << this << ".MakeBoundaryMesh( "
7027 << "SMESH." << dimName[int(dim)] << ", "
7028 << "'" << groupName << "', "
7029 << "'" << meshName<< "', "
7030 << toCopyElements << ", "
7031 << toCopyExistingBondary << ")";
7033 group = group_var._retn();
7034 return mesh_var._retn();
7036 SMESH_CATCH( SMESH::throwCorbaException );
7037 return SMESH::SMESH_Mesh::_nil();
7040 //================================================================================
7042 * \brief Creates missing boundary elements
7043 * \param dimension - defines type of boundary elements to create
7044 * \param groupName - a name of group to store all boundary elements in,
7045 * "" means not to create the group
7046 * \param meshName - a name of a new mesh, which is a copy of the initial
7047 * mesh + created boundary elements; "" means not to create the new mesh
7048 * \param toCopyAll - if true, the whole initial mesh will be copied into
7049 * the new mesh else only boundary elements will be copied into the new mesh
7050 * \param groups - optional groups of elements to make boundary around
7051 * \param mesh - returns the mesh where elements were added to
7052 * \param group - returns the created group, if any
7053 * \retval long - number of added boundary elements
7055 //================================================================================
7057 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
7058 const char* groupName,
7059 const char* meshName,
7060 CORBA::Boolean toCopyAll,
7061 const SMESH::ListOfIDSources& groups,
7062 SMESH::SMESH_Mesh_out mesh,
7063 SMESH::SMESH_Group_out group)
7064 throw (SALOME::SALOME_Exception)
7069 if ( dim > SMESH::BND_1DFROM2D )
7070 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7072 // separate groups belonging to this and other mesh
7073 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
7074 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
7075 groupsOfThisMesh->length( groups.length() );
7076 groupsOfOtherMesh->length( groups.length() );
7077 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
7078 for ( int i = 0; i < groups.length(); ++i )
7080 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
7081 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
7082 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
7084 groupsOfThisMesh[ nbGroups++ ] = groups[i];
7085 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
7086 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
7088 groupsOfThisMesh->length( nbGroups );
7089 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
7094 if ( nbGroupsOfOtherMesh > 0 )
7096 // process groups belonging to another mesh
7097 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
7098 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
7099 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
7100 groupsOfOtherMesh, mesh, group );
7103 SMESH::SMESH_Mesh_var mesh_var;
7104 SMESH::SMESH_Group_var group_var;
7107 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
7108 const bool toCopyMesh = ( strlen( meshName ) > 0 );
7112 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
7114 /*toCopyGroups=*/false,
7115 /*toKeepIDs=*/true);
7117 mesh_var = makeMesh(meshName);
7119 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7120 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
7123 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
7124 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
7126 // group of boundary elements
7127 SMESH_Group* smesh_group = 0;
7128 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
7129 if ( strlen(groupName) )
7131 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
7132 group_var = mesh_i->CreateGroup( groupType, groupName );
7133 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7134 smesh_group = group_i->GetSmeshGroup();
7137 TIDSortedElemSet elements;
7139 if ( groups.length() > 0 )
7141 for ( int i = 0; i < nbGroups; ++i )
7144 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
7146 SMESH::Bnd_Dimension bdim =
7147 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
7148 nbAdded += getEditor().MakeBoundaryMesh( elements,
7149 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
7152 /*toCopyElements=*/false,
7153 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7154 /*toAddExistingBondary=*/true,
7155 /*aroundElements=*/true);
7161 nbAdded += getEditor().MakeBoundaryMesh( elements,
7162 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7165 /*toCopyElements=*/false,
7166 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7167 /*toAddExistingBondary=*/true);
7169 tgtMesh->GetMeshDS()->Modified();
7171 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7173 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
7174 pyDump << "nbAdded, ";
7175 if ( mesh_var->_is_nil() )
7176 pyDump << myMesh_i->_this() << ", ";
7178 pyDump << mesh_var << ", ";
7179 if ( group_var->_is_nil() )
7180 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7182 pyDump << group_var << " = ";
7183 pyDump << this << ".MakeBoundaryElements( "
7184 << "SMESH." << dimName[int(dim)] << ", "
7185 << "'" << groupName << "', "
7186 << "'" << meshName<< "', "
7187 << toCopyAll << ", "
7190 mesh = mesh_var._retn();
7191 group = group_var._retn();
7194 SMESH_CATCH( SMESH::throwCorbaException );