1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_MeshEditor_i.cxx
23 // Author : Nicolas REJNERI
30 // A macro used in SMESH_TryCatch.hxx,
31 // it re-raises a CORBA SALOME exception thrown by SMESH_MeshEditor_i and caught by SMESH_CATCH
32 #define SMY_OWN_CATCH \
33 catch ( SALOME::SALOME_Exception & e ) { throw e; }
35 #include "SMESH_MeshEditor_i.hxx"
37 #include "SMDS_EdgePosition.hxx"
38 #include "SMDS_ElemIterator.hxx"
39 #include "SMDS_FacePosition.hxx"
40 #include "SMDS_IteratorOnIterators.hxx"
41 #include "SMDS_LinearEdge.hxx"
42 #include "SMDS_Mesh0DElement.hxx"
43 #include "SMDS_MeshFace.hxx"
44 #include "SMDS_MeshVolume.hxx"
45 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
46 #include "SMDS_SetIterator.hxx"
47 #include "SMDS_VolumeTool.hxx"
48 #include "SMESHDS_Group.hxx"
49 #include "SMESHDS_GroupOnGeom.hxx"
50 #include "SMESH_ControlsDef.hxx"
51 #include "SMESH_Filter_i.hxx"
52 #include "SMESH_Gen_i.hxx"
53 #include "SMESH_Group.hxx"
54 #include "SMESH_Group_i.hxx"
55 #include "SMESH_MeshAlgos.hxx"
56 #include "SMESH_MeshPartDS.hxx"
57 #include "SMESH_MesherHelper.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMeshEventListener.hxx"
60 #include "SMESH_subMesh_i.hxx"
62 #include <utilities.h>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <Utils_CorbaException.hxx>
65 #include <SALOMEDS_wrap.hxx>
66 #include <SALOME_GenericObj_i.hh>
67 #include <Basics_OCCTVersion.hxx>
69 #include <BRepAdaptor_Surface.hxx>
70 #include <BRep_Tool.hxx>
71 #include <TopExp_Explorer.hxx>
73 #include <TopoDS_Edge.hxx>
74 #include <TopoDS_Face.hxx>
79 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
83 #include <Standard_Failure.hxx>
86 #include <Standard_ErrorHandler.hxx>
92 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
94 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
97 using SMESH::TPythonDump;
100 namespace MeshEditor_I {
102 //=============================================================================
104 * \brief Mesh to apply modifications for preview purposes
106 //=============================================================================
108 struct TPreviewMesh: public SMESH_Mesh
110 SMDSAbs_ElementType myPreviewType; // type to show
112 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
113 _isShapeToMesh = (_id =_studyId = 0);
114 _myMeshDS = new SMESHDS_Mesh( _id, true );
115 myPreviewType = previewElements;
118 virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
119 //!< Copy a set of elements
120 void Copy(const TIDSortedElemSet & theElements,
121 TIDSortedElemSet& theCopyElements,
122 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
123 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
125 // loop on theIDsOfElements
126 TIDSortedElemSet::const_iterator eIt = theElements.begin();
127 for ( ; eIt != theElements.end(); ++eIt )
129 const SMDS_MeshElement* anElem = *eIt;
130 if ( !anElem ) continue;
131 SMDSAbs_ElementType type = anElem->GetType();
132 if ( type == theAvoidType ||
133 ( theSelectType != SMDSAbs_All && type != theSelectType ))
135 const SMDS_MeshElement* anElemCopy;
136 if ( type == SMDSAbs_Node)
137 anElemCopy = Copy( cast2Node(anElem) );
139 anElemCopy = Copy( anElem );
141 theCopyElements.insert( theCopyElements.end(), anElemCopy );
145 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
147 // copy element nodes
148 int anElemNbNodes = anElem->NbNodes();
149 vector< int > anElemNodesID( anElemNbNodes ) ;
150 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
151 for ( int i = 0; itElemNodes->more(); i++)
153 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
155 anElemNodesID[i] = anElemNode->GetID();
158 // creates a corresponding element on copied nodes
159 SMDS_MeshElement* anElemCopy = 0;
160 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
162 const SMDS_VtkVolume* ph =
163 dynamic_cast<const SMDS_VtkVolume*> (anElem);
165 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
166 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
169 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
176 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
178 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
179 anElemNode->GetID());
183 GetMeshDS()->ClearMesh();
185 };// struct TPreviewMesh
187 static SMESH_NodeSearcher * theNodeSearcher = 0;
188 static SMESH_ElementSearcher * theElementSearcher = 0;
190 //=============================================================================
192 * \brief Deleter of theNodeSearcher at any compute event occured
194 //=============================================================================
196 struct TSearchersDeleter : public SMESH_subMeshEventListener
199 string myMeshPartIOR;
201 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
202 "SMESH_MeshEditor_i::TSearchersDeleter"),
204 //!< Delete theNodeSearcher
207 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
208 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
210 typedef map < int, SMESH_subMesh * > TDependsOnMap;
211 //!< The meshod called by submesh: do my main job
212 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
213 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
215 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
217 Unset( sm->GetFather() );
220 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
221 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
223 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
230 myMeshPartIOR = meshPartIOR;
231 SMESH_subMesh* sm = mesh->GetSubMesh( mesh->GetShapeToMesh() );
232 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
233 while ( smIt->more() )
236 sm->SetEventListener( this, 0, sm );
240 //!< delete self from all submeshes
241 void Unset(SMESH_Mesh* mesh)
243 if ( SMESH_subMesh* sm = mesh->GetSubMeshContaining(1) ) {
244 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
245 while ( smIt->more() )
246 smIt->next()->DeleteEventListener( this );
251 } theSearchersDeleter;
253 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
255 TCollection_AsciiString typeStr;
256 switch ( theMirrorType ) {
257 case SMESH::SMESH_MeshEditor::POINT:
258 typeStr = "SMESH.SMESH_MeshEditor.POINT";
260 case SMESH::SMESH_MeshEditor::AXIS:
261 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
264 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
268 //================================================================================
270 * \brief function for conversion of long_array to TIDSortedElemSet
271 * \param IDs - array of IDs
272 * \param aMesh - mesh
273 * \param aMap - collection to fill
274 * \param aType - element type
276 //================================================================================
278 void arrayToSet(const SMESH::long_array & IDs,
279 const SMESHDS_Mesh* aMesh,
280 TIDSortedElemSet& aMap,
281 const SMDSAbs_ElementType aType = SMDSAbs_All,
282 SMDS_MeshElement::Filter* aFilter = NULL)
284 SMDS_MeshElement::NonNullFilter filter1;
285 SMDS_MeshElement::TypeFilter filter2( aType );
287 if ( aFilter == NULL )
288 aFilter = ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter*) &filter1 : (SMDS_MeshElement::Filter*) &filter2;
290 SMDS_MeshElement::Filter & filter = *aFilter;
292 if ( aType == SMDSAbs_Node )
293 for (int i=0; i<IDs.length(); i++) {
294 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
296 aMap.insert( aMap.end(), elem );
299 for (int i=0; i<IDs.length(); i++) {
300 const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
302 aMap.insert( aMap.end(), elem );
305 //================================================================================
307 * \brief Retrieve elements of given type from SMESH_IDSource
309 //================================================================================
311 enum IDSource_Error { IDSource_OK, IDSource_INVALID, IDSource_EMPTY };
313 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
314 const SMESHDS_Mesh* theMeshDS,
315 TIDSortedElemSet& theElemSet,
316 const SMDSAbs_ElementType theType,
317 const bool emptyIfIsMesh = false,
318 IDSource_Error* error = 0)
321 if ( error ) *error = IDSource_OK;
323 if ( CORBA::is_nil( theIDSource ) )
325 if ( error ) *error = IDSource_INVALID;
328 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
330 if ( error && theMeshDS->GetMeshInfo().NbElements( theType ) == 0 )
331 *error = IDSource_EMPTY;
334 SMESH::long_array_var anIDs = theIDSource->GetIDs();
335 if ( anIDs->length() == 0 )
337 if ( error ) *error = IDSource_EMPTY;
340 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
341 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
343 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
345 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
349 if ( error ) *error = IDSource_INVALID;
355 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
356 if ( bool(anIDs->length()) != bool(theElemSet.size()))
358 if ( error ) *error = IDSource_INVALID;
364 //================================================================================
366 * \brief Retrieve nodes from SMESH_IDSource
368 //================================================================================
370 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
371 const SMESHDS_Mesh* theMeshDS,
372 TIDSortedNodeSet& theNodeSet)
375 if ( CORBA::is_nil( theObject ) )
377 SMESH::array_of_ElementType_var types = theObject->GetTypes();
378 SMESH::long_array_var aElementsId = theObject->GetIDs();
379 if ( types->length() == 1 && types[0] == SMESH::NODE)
381 for(int i = 0; i < aElementsId->length(); i++)
382 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
383 theNodeSet.insert( theNodeSet.end(), n);
385 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
387 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
388 while ( nIt->more( ))
389 if( const SMDS_MeshElement * elem = nIt->next() )
390 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
394 for(int i = 0; i < aElementsId->length(); i++)
395 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
396 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
400 //================================================================================
402 * \brief Returns elements connected to the given elements
404 //================================================================================
406 void getElementsAround(const TIDSortedElemSet& theElements,
407 const SMESHDS_Mesh* theMeshDS,
408 TIDSortedElemSet& theElementsAround)
410 if ( theElements.empty() ) return;
412 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
413 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
415 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
416 return; // all the elements are in theElements
419 elemType = SMDSAbs_All;
421 vector<bool> isNodeChecked( theMeshDS->NbNodes(), false );
423 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
424 for ( ; elemIt != theElements.end(); ++elemIt )
426 const SMDS_MeshElement* e = *elemIt;
427 int i = e->NbCornerNodes();
430 const SMDS_MeshNode* n = e->GetNode( i );
431 if ( !isNodeChecked[ n->GetID() ])
433 isNodeChecked[ n->GetID() ] = true;
434 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
435 while ( invIt->more() )
437 const SMDS_MeshElement* elemAround = invIt->next();
438 if ( !theElements.count( elemAround ))
439 theElementsAround.insert( elemAround );
446 //================================================================================
448 * \brief Return a string used to detect change of mesh part on which theElementSearcher
449 * is going to be used
451 //================================================================================
453 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
455 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
456 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
457 // take into account passible group modification
458 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
459 partIOR += SMESH_Comment( type );
463 } // namespace MeshEditor_I
465 using namespace MeshEditor_I;
467 //=============================================================================
471 //=============================================================================
473 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
475 myMesh( &theMesh->GetImpl() ),
477 myIsPreviewMode ( isPreview ),
483 //================================================================================
487 //================================================================================
489 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
491 PortableServer::POA_var poa = SMESH_Gen_i::GetPOA();
492 PortableServer::ObjectId_var anObjectId = poa->servant_to_id(this);
493 poa->deactivate_object(anObjectId.in());
495 //deleteAuxIDSources();
496 delete myPreviewMesh; myPreviewMesh = 0;
497 delete myPreviewEditor; myPreviewEditor = 0;
500 //================================================================================
502 * \brief Clear members
504 //================================================================================
506 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
508 if ( myIsPreviewMode ) {
509 if ( myPreviewMesh ) myPreviewMesh->RemoveAll();
512 if ( deleteSearchers )
513 TSearchersDeleter::Delete();
515 getEditor().GetError().reset();
516 getEditor().CrearLastCreated();
519 //================================================================================
521 * \brief Increment mesh modif time and optionally record that the performed
522 * modification may influence futher mesh re-compute.
523 * \param [in] isReComputeSafe - true if the modification does not infulence
524 * futher mesh re-compute
526 //================================================================================
528 void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
530 myMesh->GetMeshDS()->Modified();
531 if ( !isReComputeSafe )
532 myMesh->SetIsModified( true );
535 //================================================================================
537 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
538 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
540 //================================================================================
542 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
544 if ( myIsPreviewMode && !myPreviewEditor ) {
545 if ( !myPreviewMesh ) getPreviewMesh();
546 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
548 return myIsPreviewMode ? *myPreviewEditor : myEditor;
551 //================================================================================
553 * \brief Initialize and return myPreviewMesh
554 * \param previewElements - type of elements to show in preview
556 * WARNING: call it once par a method!
558 //================================================================================
560 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
562 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
564 delete myPreviewEditor;
566 delete myPreviewMesh;
567 myPreviewMesh = new TPreviewMesh( previewElements );
569 myPreviewMesh->Clear();
570 return myPreviewMesh;
573 //================================================================================
575 * Return data of mesh edition preview
577 //================================================================================
579 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
580 throw (SALOME::SALOME_Exception)
583 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
585 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
587 list<int> aNodesConnectivity;
588 typedef map<int, int> TNodesMap;
591 SMESHDS_Mesh* aMeshDS;
592 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
594 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
595 aMeshDS = aMeshPartDS.get();
598 aMeshDS = getEditor().GetMeshDS();
600 myPreviewData = new SMESH::MeshPreviewStruct();
601 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
604 SMDSAbs_ElementType previewType = SMDSAbs_All;
606 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
607 previewType = aPreviewMesh->myPreviewType;
608 switch ( previewType ) {
609 case SMDSAbs_Edge : break;
610 case SMDSAbs_Face : break;
611 case SMDSAbs_Volume: break;
613 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
617 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
619 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
621 while ( itMeshElems->more() ) {
622 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
623 SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator();
624 while ( itElemNodes->more() ) {
625 const SMDS_MeshNode* aMeshNode = itElemNodes->next();
626 int aNodeID = aMeshNode->GetID();
627 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
628 if ( anIter == nodesMap.end() ) {
629 // filling the nodes coordinates
630 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
631 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
632 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
633 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
636 aNodesConnectivity.push_back(anIter->second);
639 // filling the elements types
640 SMDSAbs_ElementType aType = aMeshElem->GetType();
641 bool isPoly = aMeshElem->IsPoly();
642 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
643 myPreviewData->elementTypes[i].isPoly = isPoly;
644 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
647 myPreviewData->nodesXYZ.length( j );
649 // filling the elements connectivities
650 list<int>::iterator aConnIter = aNodesConnectivity.begin();
651 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
652 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
653 myPreviewData->elementConnectivities[i] = *aConnIter;
655 return myPreviewData._retn();
657 SMESH_CATCH( SMESH::throwCorbaException );
661 //================================================================================
663 * \brief Returns list of it's IDs of created nodes
664 * \retval SMESH::long_array* - list of node ID
666 //================================================================================
668 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
669 throw (SALOME::SALOME_Exception)
672 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
674 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
675 myLastCreatedNodes->length( aSeq.Length() );
676 for (int i = 1; i <= aSeq.Length(); i++)
677 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
679 return myLastCreatedNodes._retn();
680 SMESH_CATCH( SMESH::throwCorbaException );
684 //================================================================================
686 * \brief Returns list of it's IDs of created elements
687 * \retval SMESH::long_array* - list of elements' ID
689 //================================================================================
691 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
692 throw (SALOME::SALOME_Exception)
695 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
697 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
698 myLastCreatedElems->length( aSeq.Length() );
699 for ( int i = 1; i <= aSeq.Length(); i++ )
700 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
702 return myLastCreatedElems._retn();
703 SMESH_CATCH( SMESH::throwCorbaException );
707 //=======================================================================
708 //function : ClearLastCreated
709 //purpose : Clears sequences of last created elements and nodes
710 //=======================================================================
712 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
715 getEditor().CrearLastCreated();
716 SMESH_CATCH( SMESH::throwCorbaException );
719 //=======================================================================
721 * Returns description of an error/warning occured during the last operation
722 * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
724 //=======================================================================
726 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
727 throw (SALOME::SALOME_Exception)
730 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
731 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
732 if ( errIn && !errIn->IsOK() )
734 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
735 errOut->comment = errIn->myComment.c_str();
736 errOut->subShapeID = -1;
737 errOut->hasBadMesh = !errIn->myBadElements.empty();
742 errOut->subShapeID = -1;
743 errOut->hasBadMesh = false;
746 return errOut._retn();
747 SMESH_CATCH( SMESH::throwCorbaException );
751 //=======================================================================
752 //function : MakeIDSource
753 //purpose : Wrap a sequence of ids in a SMESH_IDSource.
754 // Call UnRegister() as you fininsh using it!!
755 //=======================================================================
757 struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource,
758 public virtual SALOME::GenericObj_i
760 SMESH::long_array _ids;
761 SMESH::ElementType _type;
762 SMESH::SMESH_Mesh_ptr _mesh;
763 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
764 SMESH::long_array* GetMeshInfo() { return 0; }
765 SMESH::long_array* GetNbElementsByType()
767 SMESH::long_array_var aRes = new SMESH::long_array();
768 aRes->length(SMESH::NB_ELEMENT_TYPES);
769 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
770 aRes[ i ] = ( i == _type ) ? _ids.length() : 0;
773 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
774 bool IsMeshInfoCorrect() { return true; }
775 SMESH::array_of_ElementType* GetTypes()
777 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
778 if ( _ids.length() > 0 ) {
782 return types._retn();
784 SALOMEDS::TMPFile* GetVtkUgStream()
786 SALOMEDS::TMPFile_var SeqFile;
787 return SeqFile._retn();
791 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
792 SMESH::ElementType type)
794 _IDSource* idSrc = new _IDSource;
795 idSrc->_mesh = myMesh_i->_this();
798 if ( type == SMESH::ALL && ids.length() > 0 )
799 idSrc->_type = myMesh_i->GetElementType( ids[0], true );
801 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
803 return anIDSourceVar._retn();
806 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
808 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
811 CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource,
814 if ( _IDSource* tmpIdSource = SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource ))
816 nbIds = (int) tmpIdSource->_ids.length();
817 return & tmpIdSource->_ids[0];
823 // void SMESH_MeshEditor_i::deleteAuxIDSources()
825 // std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
826 // for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
828 // myAuxIDSources.clear();
831 //=============================================================================
835 //=============================================================================
838 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
839 throw (SALOME::SALOME_Exception)
846 for (int i = 0; i < IDsOfElements.length(); i++)
847 IdList.push_back( IDsOfElements[i] );
849 // Update Python script
850 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
853 bool ret = getEditor().Remove( IdList, false );
855 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
858 SMESH_CATCH( SMESH::throwCorbaException );
862 //=============================================================================
866 //=============================================================================
868 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
869 throw (SALOME::SALOME_Exception)
875 for (int i = 0; i < IDsOfNodes.length(); i++)
876 IdList.push_back( IDsOfNodes[i] );
878 // Update Python script
879 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
881 bool ret = getEditor().Remove( IdList, true );
883 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
886 SMESH_CATCH( SMESH::throwCorbaException );
890 //=============================================================================
894 //=============================================================================
896 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
897 throw (SALOME::SALOME_Exception)
902 // Update Python script
903 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
905 // Create filter to find all orphan nodes
906 SMESH::Controls::Filter::TIdSequence seq;
907 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
908 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
910 // remove orphan nodes (if there are any)
912 for ( int i = 0; i < seq.size(); i++ )
913 IdList.push_back( seq[i] );
915 int nbNodesBefore = myMesh->NbNodes();
916 getEditor().Remove( IdList, true );
917 int nbNodesAfter = myMesh->NbNodes();
919 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
920 return nbNodesBefore - nbNodesAfter;
922 SMESH_CATCH( SMESH::throwCorbaException );
926 //=============================================================================
930 //=============================================================================
932 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
933 throw (SALOME::SALOME_Exception)
938 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
940 // Update Python script
941 TPythonDump() << "nodeID = " << this << ".AddNode( "
942 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
944 declareMeshModified( /*isReComputeSafe=*/false );
947 SMESH_CATCH( SMESH::throwCorbaException );
951 //=============================================================================
953 * Create 0D element on the given node.
955 //=============================================================================
957 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
958 throw (SALOME::SALOME_Exception)
963 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
964 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
966 // Update Python script
967 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
969 declareMeshModified( /*isReComputeSafe=*/false );
971 return elem ? elem->GetID() : 0;
973 SMESH_CATCH( SMESH::throwCorbaException );
977 //=============================================================================
979 * Create a ball element on the given node.
981 //=============================================================================
983 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
984 throw (SALOME::SALOME_Exception)
989 if ( diameter < std::numeric_limits<double>::min() )
990 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
992 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
993 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
995 // Update Python script
996 TPythonDump() << "ballElem = "
997 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
999 declareMeshModified( /*isReComputeSafe=*/false );
1000 return elem ? elem->GetID() : 0;
1002 SMESH_CATCH( SMESH::throwCorbaException );
1006 //=============================================================================
1008 * Create an edge, either linear and quadratic (this is determed
1009 * by number of given nodes, two or three)
1011 //=============================================================================
1013 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
1014 throw (SALOME::SALOME_Exception)
1019 int NbNodes = IDsOfNodes.length();
1020 SMDS_MeshElement* elem = 0;
1023 CORBA::Long index1 = IDsOfNodes[0];
1024 CORBA::Long index2 = IDsOfNodes[1];
1025 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
1026 getMeshDS()->FindNode(index2));
1028 // Update Python script
1029 TPythonDump() << "edge = " << this << ".AddEdge([ "
1030 << index1 << ", " << index2 <<" ])";
1033 CORBA::Long n1 = IDsOfNodes[0];
1034 CORBA::Long n2 = IDsOfNodes[1];
1035 CORBA::Long n12 = IDsOfNodes[2];
1036 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
1037 getMeshDS()->FindNode(n2),
1038 getMeshDS()->FindNode(n12));
1039 // Update Python script
1040 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
1041 <<n1<<", "<<n2<<", "<<n12<<" ])";
1044 declareMeshModified( /*isReComputeSafe=*/false );
1045 return elem ? elem->GetID() : 0;
1047 SMESH_CATCH( SMESH::throwCorbaException );
1051 //=============================================================================
1055 //=============================================================================
1057 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1058 throw (SALOME::SALOME_Exception)
1063 int NbNodes = IDsOfNodes.length();
1069 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1070 for (int i = 0; i < NbNodes; i++)
1071 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1073 SMDS_MeshElement* elem = 0;
1075 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1076 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1077 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1078 nodes[4], nodes[5]); break;
1079 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1080 nodes[4], nodes[5], nodes[6]); break;
1081 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1082 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1083 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1084 nodes[4], nodes[5], nodes[6], nodes[7],
1086 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1089 // Update Python script
1090 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1092 declareMeshModified( /*isReComputeSafe=*/false );
1094 return elem ? elem->GetID() : 0;
1096 SMESH_CATCH( SMESH::throwCorbaException );
1100 //=============================================================================
1104 //=============================================================================
1105 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1106 throw (SALOME::SALOME_Exception)
1111 int NbNodes = IDsOfNodes.length();
1112 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1113 for (int i = 0; i < NbNodes; i++)
1114 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1116 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1118 // Update Python script
1119 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1121 declareMeshModified( /*isReComputeSafe=*/false );
1122 return elem ? elem->GetID() : 0;
1124 SMESH_CATCH( SMESH::throwCorbaException );
1128 //=============================================================================
1130 * Create volume, either linear and quadratic (this is determed
1131 * by number of given nodes)
1133 //=============================================================================
1135 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1136 throw (SALOME::SALOME_Exception)
1141 int NbNodes = IDsOfNodes.length();
1142 vector< const SMDS_MeshNode*> n(NbNodes);
1143 for(int i=0;i<NbNodes;i++)
1144 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1146 SMDS_MeshElement* elem = 0;
1149 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1150 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1151 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1152 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1153 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1154 n[6],n[7],n[8],n[9]);
1156 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1157 n[6],n[7],n[8],n[9],n[10],n[11]);
1159 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1160 n[7],n[8],n[9],n[10],n[11],n[12]);
1162 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1163 n[9],n[10],n[11],n[12],n[13],n[14]);
1165 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1166 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1167 n[15],n[16],n[17],n[18],n[19]);
1169 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1170 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1171 n[15],n[16],n[17],n[18],n[19],
1172 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1176 // Update Python script
1177 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1179 declareMeshModified( /*isReComputeSafe=*/false );
1180 return elem ? elem->GetID() : 0;
1182 SMESH_CATCH( SMESH::throwCorbaException );
1186 //=============================================================================
1188 * AddPolyhedralVolume
1190 //=============================================================================
1191 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1192 const SMESH::long_array & Quantities)
1193 throw (SALOME::SALOME_Exception)
1198 int NbNodes = IDsOfNodes.length();
1199 std::vector<const SMDS_MeshNode*> n (NbNodes);
1200 for (int i = 0; i < NbNodes; i++)
1202 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1203 if (!aNode) return 0;
1207 int NbFaces = Quantities.length();
1208 std::vector<int> q (NbFaces);
1209 for (int j = 0; j < NbFaces; j++)
1210 q[j] = Quantities[j];
1212 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1214 // Update Python script
1215 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1216 << IDsOfNodes << ", " << Quantities << " )";
1218 declareMeshModified( /*isReComputeSafe=*/false );
1219 return elem ? elem->GetID() : 0;
1221 SMESH_CATCH( SMESH::throwCorbaException );
1225 //=============================================================================
1227 * AddPolyhedralVolumeByFaces
1229 //=============================================================================
1231 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1232 throw (SALOME::SALOME_Exception)
1237 int NbFaces = IdsOfFaces.length();
1238 std::vector<const SMDS_MeshNode*> poly_nodes;
1239 std::vector<int> quantities (NbFaces);
1241 for (int i = 0; i < NbFaces; i++) {
1242 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1243 quantities[i] = aFace->NbNodes();
1245 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1246 while (It->more()) {
1247 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1251 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1253 // Update Python script
1254 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1255 << IdsOfFaces << " )";
1257 declareMeshModified( /*isReComputeSafe=*/false );
1258 return elem ? elem->GetID() : 0;
1260 SMESH_CATCH( SMESH::throwCorbaException );
1264 //=============================================================================
1266 // \brief Create 0D elements on all nodes of the given object except those
1267 // nodes on which a 0D element already exists.
1268 // \param theObject object on whose nodes 0D elements will be created.
1269 // \param theGroupName optional name of a group to add 0D elements created
1270 // and/or found on nodes of \a theObject.
1271 // \return an object (a new group or a temporary SMESH_IDSource) holding
1272 // ids of new and/or found 0D elements.
1274 //=============================================================================
1276 SMESH::SMESH_IDSource_ptr
1277 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1278 const char* theGroupName)
1279 throw (SALOME::SALOME_Exception)
1284 SMESH::SMESH_IDSource_var result;
1287 TIDSortedElemSet elements, elems0D;
1288 prepareIdSource( theObject );
1289 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1290 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1292 SMESH::long_array_var newElems = new SMESH::long_array;
1293 newElems->length( elems0D.size() );
1294 TIDSortedElemSet::iterator eIt = elems0D.begin();
1295 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1296 newElems[ i ] = (*eIt)->GetID();
1298 SMESH::SMESH_GroupBase_var groupToFill;
1299 if ( theGroupName && strlen( theGroupName ))
1301 // Get existing group named theGroupName
1302 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1303 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1304 SMESH::SMESH_GroupBase_var group = groups[i];
1305 if ( !group->_is_nil() ) {
1306 CORBA::String_var name = group->GetName();
1307 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1308 groupToFill = group;
1313 if ( groupToFill->_is_nil() )
1314 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1315 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1316 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1319 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1321 group_i->Add( newElems );
1322 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1323 pyDump << groupToFill;
1327 result = MakeIDSource( newElems, SMESH::ELEM0D );
1328 pyDump << "elem0DIDs";
1331 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1332 << theObject << ", '" << theGroupName << "' )";
1334 return result._retn();
1336 SMESH_CATCH( SMESH::throwCorbaException );
1340 //=============================================================================
1342 * \brief Bind a node to a vertex
1343 * \param NodeID - node ID
1344 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1345 * \retval boolean - false if NodeID or VertexID is invalid
1347 //=============================================================================
1349 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1350 throw (SALOME::SALOME_Exception)
1354 SMESHDS_Mesh * mesh = getMeshDS();
1355 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1357 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1359 if ( mesh->MaxShapeIndex() < VertexID )
1360 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1362 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1363 if ( shape.ShapeType() != TopAbs_VERTEX )
1364 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1366 mesh->SetNodeOnVertex( node, VertexID );
1368 myMesh->SetIsModified( true );
1370 SMESH_CATCH( SMESH::throwCorbaException );
1373 //=============================================================================
1375 * \brief Store node position on an edge
1376 * \param NodeID - node ID
1377 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1378 * \param paramOnEdge - parameter on edge where the node is located
1379 * \retval boolean - false if any parameter is invalid
1381 //=============================================================================
1383 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1384 CORBA::Double paramOnEdge)
1385 throw (SALOME::SALOME_Exception)
1389 SMESHDS_Mesh * mesh = getMeshDS();
1390 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1392 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1394 if ( mesh->MaxShapeIndex() < EdgeID )
1395 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1397 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1398 if ( shape.ShapeType() != TopAbs_EDGE )
1399 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1402 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1403 if ( paramOnEdge < f || paramOnEdge > l )
1404 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1406 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1408 myMesh->SetIsModified( true );
1410 SMESH_CATCH( SMESH::throwCorbaException );
1413 //=============================================================================
1415 * \brief Store node position on a face
1416 * \param NodeID - node ID
1417 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1418 * \param u - U parameter on face where the node is located
1419 * \param v - V parameter on face where the node is located
1420 * \retval boolean - false if any parameter is invalid
1422 //=============================================================================
1424 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1425 CORBA::Double u, CORBA::Double v)
1426 throw (SALOME::SALOME_Exception)
1429 SMESHDS_Mesh * mesh = getMeshDS();
1430 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1432 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1434 if ( mesh->MaxShapeIndex() < FaceID )
1435 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1437 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1438 if ( shape.ShapeType() != TopAbs_FACE )
1439 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1441 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1442 bool isOut = ( u < surf.FirstUParameter() ||
1443 u > surf.LastUParameter() ||
1444 v < surf.FirstVParameter() ||
1445 v > surf.LastVParameter() );
1449 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1450 << " u( " << surf.FirstUParameter()
1451 << "," << surf.LastUParameter()
1452 << ") v( " << surf.FirstVParameter()
1453 << "," << surf.LastVParameter() << ")" );
1455 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1458 mesh->SetNodeOnFace( node, FaceID, u, v );
1459 myMesh->SetIsModified( true );
1461 SMESH_CATCH( SMESH::throwCorbaException );
1464 //=============================================================================
1466 * \brief Bind a node to a solid
1467 * \param NodeID - node ID
1468 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1469 * \retval boolean - false if NodeID or SolidID is invalid
1471 //=============================================================================
1473 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1474 throw (SALOME::SALOME_Exception)
1477 SMESHDS_Mesh * mesh = getMeshDS();
1478 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1480 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1482 if ( mesh->MaxShapeIndex() < SolidID )
1483 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1485 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1486 if ( shape.ShapeType() != TopAbs_SOLID &&
1487 shape.ShapeType() != TopAbs_SHELL)
1488 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1490 mesh->SetNodeInVolume( node, SolidID );
1492 SMESH_CATCH( SMESH::throwCorbaException );
1495 //=============================================================================
1497 * \brief Bind an element to a shape
1498 * \param ElementID - element ID
1499 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1501 //=============================================================================
1503 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1504 CORBA::Long ShapeID)
1505 throw (SALOME::SALOME_Exception)
1508 SMESHDS_Mesh * mesh = getMeshDS();
1509 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1511 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1513 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1514 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1516 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1517 if ( shape.ShapeType() != TopAbs_EDGE &&
1518 shape.ShapeType() != TopAbs_FACE &&
1519 shape.ShapeType() != TopAbs_SOLID &&
1520 shape.ShapeType() != TopAbs_SHELL )
1521 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1523 mesh->SetMeshElementOnShape( elem, ShapeID );
1525 myMesh->SetIsModified( true );
1527 SMESH_CATCH( SMESH::throwCorbaException );
1530 //=============================================================================
1534 //=============================================================================
1536 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1537 CORBA::Long NodeID2)
1538 throw (SALOME::SALOME_Exception)
1543 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1544 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1548 // Update Python script
1549 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1550 << NodeID1 << ", " << NodeID2 << " )";
1552 int ret = getEditor().InverseDiag ( n1, n2 );
1554 declareMeshModified( /*isReComputeSafe=*/false );
1557 SMESH_CATCH( SMESH::throwCorbaException );
1561 //=============================================================================
1565 //=============================================================================
1567 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1568 CORBA::Long NodeID2)
1569 throw (SALOME::SALOME_Exception)
1574 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1575 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1579 // Update Python script
1580 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1581 << NodeID1 << ", " << NodeID2 << " )";
1584 bool stat = getEditor().DeleteDiag ( n1, n2 );
1586 declareMeshModified( /*isReComputeSafe=*/!stat );
1590 SMESH_CATCH( SMESH::throwCorbaException );
1594 //=============================================================================
1598 //=============================================================================
1600 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1601 throw (SALOME::SALOME_Exception)
1606 for (int i = 0; i < IDsOfElements.length(); i++)
1608 CORBA::Long index = IDsOfElements[i];
1609 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1611 getEditor().Reorient( elem );
1613 // Update Python script
1614 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1616 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1619 SMESH_CATCH( SMESH::throwCorbaException );
1623 //=============================================================================
1627 //=============================================================================
1629 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1630 throw (SALOME::SALOME_Exception)
1635 TPythonDump aTPythonDump; // suppress dump in Reorient()
1637 prepareIdSource( theObject );
1639 SMESH::long_array_var anElementsId = theObject->GetIDs();
1640 CORBA::Boolean isDone = Reorient(anElementsId);
1642 // Update Python script
1643 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1645 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1648 SMESH_CATCH( SMESH::throwCorbaException );
1652 //=======================================================================
1653 //function : Reorient2D
1654 //purpose : Reorient faces contained in \a the2Dgroup.
1655 // the2Dgroup - the mesh or its part to reorient
1656 // theDirection - desired direction of normal of \a theFace
1657 // theFace - ID of face whose orientation is checked.
1658 // It can be < 1 then \a thePoint is used to find a face.
1659 // thePoint - is used to find a face if \a theFace < 1.
1660 // return number of reoriented elements.
1661 //=======================================================================
1663 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1664 const SMESH::DirStruct& theDirection,
1665 CORBA::Long theFace,
1666 const SMESH::PointStruct& thePoint)
1667 throw (SALOME::SALOME_Exception)
1670 initData(/*deleteSearchers=*/false);
1672 TIDSortedElemSet elements;
1673 prepareIdSource( the2Dgroup );
1674 IDSource_Error error;
1675 idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1676 if ( error == IDSource_EMPTY )
1678 if ( error == IDSource_INVALID )
1679 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1682 const SMDS_MeshElement* face = 0;
1685 face = getMeshDS()->FindElement( theFace );
1687 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1688 if ( face->GetType() != SMDSAbs_Face )
1689 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1693 // create theElementSearcher if needed
1694 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1695 if ( !theElementSearcher )
1697 if ( elements.empty() ) // search in the whole mesh
1699 if ( myMesh->NbFaces() == 0 )
1700 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1702 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1706 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1707 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1709 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1713 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1714 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1717 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1718 if ( !elements.empty() && !elements.count( face ))
1719 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1722 const SMESH::PointStruct * P = &theDirection.PS;
1723 gp_Vec dirVec( P->x, P->y, P->z );
1724 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1725 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1727 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1730 declareMeshModified( /*isReComputeSafe=*/false );
1732 TPythonDump() << this << ".Reorient2D( "
1733 << the2Dgroup << ", "
1734 << theDirection << ", "
1736 << thePoint << " )";
1740 SMESH_CATCH( SMESH::throwCorbaException );
1744 //=======================================================================
1745 //function : Reorient2DBy3D
1746 //purpose : Reorient faces basing on orientation of adjacent volumes.
1747 //=======================================================================
1749 CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& faceGroups,
1750 SMESH::SMESH_IDSource_ptr volumeGroup,
1751 CORBA::Boolean outsideNormal)
1752 throw (SALOME::SALOME_Exception)
1757 TIDSortedElemSet volumes;
1758 prepareIdSource( volumeGroup );
1759 IDSource_Error volsError;
1760 idSourceToSet( volumeGroup, getMeshDS(), volumes, SMDSAbs_Volume, /*emptyIfMesh=*/1, &volsError);
1763 for ( size_t i = 0; i < faceGroups.length(); ++i )
1765 SMESH::SMESH_IDSource_ptr faceGrp = faceGroups[i].in();
1766 prepareIdSource( faceGrp );
1768 TIDSortedElemSet faces;
1769 IDSource_Error error;
1770 idSourceToSet( faceGrp, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1771 if ( error == IDSource_INVALID && faceGroups.length() == 1 )
1772 THROW_SALOME_CORBA_EXCEPTION("No faces in a given object", SALOME::BAD_PARAM);
1773 if ( error == IDSource_OK && volsError != IDSource_OK )
1774 THROW_SALOME_CORBA_EXCEPTION("No volumes in a given object", SALOME::BAD_PARAM);
1776 nbReori += getEditor().Reorient2DBy3D( faces, volumes, outsideNormal );
1778 if ( error != IDSource_EMPTY && faces.empty() ) // all faces in the mesh treated
1783 declareMeshModified( /*isReComputeSafe=*/false );
1785 TPythonDump() << this << ".Reorient2DBy3D( "
1786 << faceGroups << ", "
1787 << volumeGroup << ", "
1788 << outsideNormal << " )";
1792 SMESH_CATCH( SMESH::throwCorbaException );
1796 //=============================================================================
1798 * \brief Fuse neighbour triangles into quadrangles.
1800 //=============================================================================
1802 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1803 SMESH::NumericalFunctor_ptr Criterion,
1804 CORBA::Double MaxAngle)
1805 throw (SALOME::SALOME_Exception)
1810 SMESHDS_Mesh* aMesh = getMeshDS();
1811 TIDSortedElemSet faces,copyFaces;
1812 SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE);
1813 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter);
1814 TIDSortedElemSet* workElements = & faces;
1816 if ( myIsPreviewMode ) {
1817 SMDSAbs_ElementType select = SMDSAbs_Face;
1818 getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select );
1819 workElements = & copyFaces;
1822 SMESH::NumericalFunctor_i* aNumericalFunctor =
1823 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1824 SMESH::Controls::NumericalFunctorPtr aCrit;
1825 if ( !aNumericalFunctor )
1826 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1828 aCrit = aNumericalFunctor->GetNumericalFunctor();
1830 if ( !myIsPreviewMode ) {
1831 // Update Python script
1832 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1833 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1836 bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle );
1838 declareMeshModified( /*isReComputeSafe=*/!stat );
1841 SMESH_CATCH( SMESH::throwCorbaException );
1845 //=============================================================================
1847 * \brief Fuse neighbour triangles into quadrangles.
1849 //=============================================================================
1851 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1852 SMESH::NumericalFunctor_ptr Criterion,
1853 CORBA::Double MaxAngle)
1854 throw (SALOME::SALOME_Exception)
1859 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1861 prepareIdSource( theObject );
1862 SMESH::long_array_var anElementsId = theObject->GetIDs();
1863 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1865 if ( !myIsPreviewMode ) {
1866 SMESH::NumericalFunctor_i* aNumericalFunctor =
1867 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1869 // Update Python script
1870 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1871 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1876 SMESH_CATCH( SMESH::throwCorbaException );
1880 //=============================================================================
1882 * \brief Split quadrangles into triangles.
1884 //=============================================================================
1886 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1887 SMESH::NumericalFunctor_ptr Criterion)
1888 throw (SALOME::SALOME_Exception)
1893 SMESHDS_Mesh* aMesh = getMeshDS();
1894 TIDSortedElemSet faces;
1895 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1897 SMESH::NumericalFunctor_i* aNumericalFunctor =
1898 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1899 SMESH::Controls::NumericalFunctorPtr aCrit;
1900 if ( !aNumericalFunctor )
1901 aCrit.reset( new SMESH::Controls::AspectRatio() );
1903 aCrit = aNumericalFunctor->GetNumericalFunctor();
1906 // Update Python script
1907 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1909 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1911 declareMeshModified( /*isReComputeSafe=*/false );
1914 SMESH_CATCH( SMESH::throwCorbaException );
1918 //=============================================================================
1920 * \brief Split quadrangles into triangles.
1922 //=============================================================================
1924 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1925 SMESH::NumericalFunctor_ptr Criterion)
1926 throw (SALOME::SALOME_Exception)
1931 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1933 prepareIdSource( theObject );
1934 SMESH::long_array_var anElementsId = theObject->GetIDs();
1935 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1937 SMESH::NumericalFunctor_i* aNumericalFunctor =
1938 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1940 // Update Python script
1941 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1943 declareMeshModified( /*isReComputeSafe=*/false );
1946 SMESH_CATCH( SMESH::throwCorbaException );
1950 //================================================================================
1952 * \brief Split each of quadrangles into 4 triangles.
1953 * \param [in] theObject - theQuads Container of quadrangles to split.
1955 //================================================================================
1957 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1958 throw (SALOME::SALOME_Exception)
1963 TIDSortedElemSet faces;
1964 prepareIdSource( theObject );
1965 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1967 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1969 getEditor().QuadTo4Tri( faces );
1970 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1972 SMESH_CATCH( SMESH::throwCorbaException );
1975 //=============================================================================
1977 * \brief Split quadrangles into triangles.
1979 //=============================================================================
1981 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1982 CORBA::Boolean Diag13)
1983 throw (SALOME::SALOME_Exception)
1988 SMESHDS_Mesh* aMesh = getMeshDS();
1989 TIDSortedElemSet faces;
1990 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1992 // Update Python script
1993 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1994 << IDsOfElements << ", " << Diag13 << " )";
1996 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1998 declareMeshModified( /*isReComputeSafe=*/ !stat );
2001 SMESH_CATCH( SMESH::throwCorbaException );
2005 //=============================================================================
2007 * \brief Split quadrangles into triangles.
2009 //=============================================================================
2011 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
2012 CORBA::Boolean Diag13)
2013 throw (SALOME::SALOME_Exception)
2018 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
2020 prepareIdSource( theObject );
2021 SMESH::long_array_var anElementsId = theObject->GetIDs();
2022 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
2024 // Update Python script
2025 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
2026 << theObject << ", " << Diag13 << " )";
2028 declareMeshModified( /*isReComputeSafe=*/!isDone );
2031 SMESH_CATCH( SMESH::throwCorbaException );
2036 //=============================================================================
2038 * Find better splitting of the given quadrangle.
2039 * \param IDOfQuad ID of the quadrangle to be splitted.
2040 * \param Criterion A criterion to choose a diagonal for splitting.
2041 * \return 1 if 1-3 diagonal is better, 2 if 2-4
2042 * diagonal is better, 0 if error occurs.
2044 //=============================================================================
2046 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
2047 SMESH::NumericalFunctor_ptr Criterion)
2048 throw (SALOME::SALOME_Exception)
2053 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
2054 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
2056 SMESH::NumericalFunctor_i* aNumericalFunctor =
2057 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
2058 SMESH::Controls::NumericalFunctorPtr aCrit;
2059 if (aNumericalFunctor)
2060 aCrit = aNumericalFunctor->GetNumericalFunctor();
2062 aCrit.reset(new SMESH::Controls::AspectRatio());
2064 int id = getEditor().BestSplit(quad, aCrit);
2065 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
2069 SMESH_CATCH( SMESH::throwCorbaException );
2073 //================================================================================
2075 * \brief Split volumic elements into tetrahedrons
2077 //================================================================================
2079 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
2080 CORBA::Short methodFlags)
2081 throw (SALOME::SALOME_Exception)
2085 prepareIdSource( elems );
2087 ::SMESH_MeshEditor::TFacetOfElem elemSet;
2088 const int noneFacet = -1;
2089 SMDS_ElemIteratorPtr volIt = myMesh_i->GetElements( elems, SMESH::VOLUME );
2090 while( volIt->more() )
2091 elemSet.insert( elemSet.end(), make_pair( volIt->next(), noneFacet ));
2093 getEditor().SplitVolumes( elemSet, int( methodFlags ));
2094 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2096 TPythonDump() << this << ".SplitVolumesIntoTetra( "
2097 << elems << ", " << methodFlags << " )";
2099 SMESH_CATCH( SMESH::throwCorbaException );
2102 //================================================================================
2104 * \brief Split hexahedra into triangular prisms
2105 * \param elems - elements to split
2106 * \param facetToSplitNormal - normal used to find a facet of hexahedron
2107 * to split into triangles
2108 * \param methodFlags - flags passing splitting method:
2109 * 1 - split the hexahedron into 2 prisms
2110 * 2 - split the hexahedron into 4 prisms
2112 //================================================================================
2114 void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms (SMESH::SMESH_IDSource_ptr elems,
2115 const SMESH::PointStruct & startHexPoint,
2116 const SMESH::DirStruct& facetToSplitNormal,
2117 CORBA::Short methodFlags,
2118 CORBA::Boolean allDomains)
2119 throw (SALOME::SALOME_Exception)
2123 prepareIdSource( elems );
2125 gp_Ax1 facetNorm( gp_Pnt( startHexPoint.x,
2128 gp_Dir( facetToSplitNormal.PS.x,
2129 facetToSplitNormal.PS.y,
2130 facetToSplitNormal.PS.z ));
2131 TIDSortedElemSet elemSet;
2132 SMESH::long_array_var anElementsId = elems->GetIDs();
2133 SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA );
2134 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter );
2136 ::SMESH_MeshEditor::TFacetOfElem elemFacets;
2137 while ( !elemSet.empty() )
2139 getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets );
2143 ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin();
2144 for ( ; ef != elemFacets.end(); ++ef )
2145 elemSet.erase( ef->first );
2148 if ( methodFlags == 2 )
2149 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS );
2151 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS );
2153 getEditor().SplitVolumes( elemFacets, int( methodFlags ));
2154 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2156 TPythonDump() << this << ".SplitHexahedraIntoPrisms( "
2158 << startHexPoint << ", "
2159 << facetToSplitNormal<< ", "
2160 << methodFlags<< ", "
2161 << allDomains << " )";
2163 SMESH_CATCH( SMESH::throwCorbaException );
2166 //=======================================================================
2169 //=======================================================================
2172 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2173 const SMESH::long_array & IDsOfFixedNodes,
2174 CORBA::Long MaxNbOfIterations,
2175 CORBA::Double MaxAspectRatio,
2176 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2177 throw (SALOME::SALOME_Exception)
2179 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2180 MaxAspectRatio, Method, false );
2184 //=======================================================================
2185 //function : SmoothParametric
2187 //=======================================================================
2190 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2191 const SMESH::long_array & IDsOfFixedNodes,
2192 CORBA::Long MaxNbOfIterations,
2193 CORBA::Double MaxAspectRatio,
2194 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2195 throw (SALOME::SALOME_Exception)
2197 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2198 MaxAspectRatio, Method, true );
2202 //=======================================================================
2203 //function : SmoothObject
2205 //=======================================================================
2208 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2209 const SMESH::long_array & IDsOfFixedNodes,
2210 CORBA::Long MaxNbOfIterations,
2211 CORBA::Double MaxAspectRatio,
2212 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2213 throw (SALOME::SALOME_Exception)
2215 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2216 MaxAspectRatio, Method, false);
2220 //=======================================================================
2221 //function : SmoothParametricObject
2223 //=======================================================================
2226 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2227 const SMESH::long_array & IDsOfFixedNodes,
2228 CORBA::Long MaxNbOfIterations,
2229 CORBA::Double MaxAspectRatio,
2230 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2231 throw (SALOME::SALOME_Exception)
2233 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2234 MaxAspectRatio, Method, true);
2238 //=============================================================================
2242 //=============================================================================
2245 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2246 const SMESH::long_array & IDsOfFixedNodes,
2247 CORBA::Long MaxNbOfIterations,
2248 CORBA::Double MaxAspectRatio,
2249 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2251 throw (SALOME::SALOME_Exception)
2256 SMESHDS_Mesh* aMesh = getMeshDS();
2258 TIDSortedElemSet elements;
2259 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2261 set<const SMDS_MeshNode*> fixedNodes;
2262 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
2263 CORBA::Long index = IDsOfFixedNodes[i];
2264 const SMDS_MeshNode * node = aMesh->FindNode(index);
2266 fixedNodes.insert( node );
2268 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2269 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2270 method = ::SMESH_MeshEditor::CENTROIDAL;
2272 getEditor().Smooth(elements, fixedNodes, method,
2273 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2275 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2277 // Update Python script
2278 TPythonDump() << "isDone = " << this << "."
2279 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2280 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2281 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2282 << "SMESH.SMESH_MeshEditor."
2283 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2284 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2288 SMESH_CATCH( SMESH::throwCorbaException );
2292 //=============================================================================
2296 //=============================================================================
2299 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2300 const SMESH::long_array & IDsOfFixedNodes,
2301 CORBA::Long MaxNbOfIterations,
2302 CORBA::Double MaxAspectRatio,
2303 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2305 throw (SALOME::SALOME_Exception)
2310 TPythonDump aTPythonDump; // suppress dump in smooth()
2312 prepareIdSource( theObject );
2313 SMESH::long_array_var anElementsId = theObject->GetIDs();
2314 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2315 MaxAspectRatio, Method, IsParametric);
2317 // Update Python script
2318 aTPythonDump << "isDone = " << this << "."
2319 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2320 << theObject << ", " << IDsOfFixedNodes << ", "
2321 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2322 << "SMESH.SMESH_MeshEditor."
2323 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2324 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2328 SMESH_CATCH( SMESH::throwCorbaException );
2332 //=============================================================================
2336 //=============================================================================
2338 void SMESH_MeshEditor_i::RenumberNodes()
2339 throw (SALOME::SALOME_Exception)
2342 // Update Python script
2343 TPythonDump() << this << ".RenumberNodes()";
2345 getMeshDS()->Renumber( true );
2347 SMESH_CATCH( SMESH::throwCorbaException );
2350 //=============================================================================
2354 //=============================================================================
2356 void SMESH_MeshEditor_i::RenumberElements()
2357 throw (SALOME::SALOME_Exception)
2360 // Update Python script
2361 TPythonDump() << this << ".RenumberElements()";
2363 getMeshDS()->Renumber( false );
2365 SMESH_CATCH( SMESH::throwCorbaException );
2368 //=======================================================================
2370 * \brief Return groups by their IDs
2372 //=======================================================================
2374 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2375 throw (SALOME::SALOME_Exception)
2380 myMesh_i->CreateGroupServants();
2381 return myMesh_i->GetGroups( *groupIDs );
2383 SMESH_CATCH( SMESH::throwCorbaException );
2387 //=======================================================================
2388 //function : rotationSweep
2390 //=======================================================================
2392 SMESH::ListOfGroups*
2393 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2394 const SMESH::AxisStruct & theAxis,
2395 CORBA::Double theAngleInRadians,
2396 CORBA::Long theNbOfSteps,
2397 CORBA::Double theTolerance,
2398 const bool theMakeGroups,
2399 const SMDSAbs_ElementType theElementType)
2400 throw (SALOME::SALOME_Exception)
2405 TIDSortedElemSet inElements, copyElements;
2406 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2408 TIDSortedElemSet* workElements = & inElements;
2409 bool makeWalls=true;
2410 if ( myIsPreviewMode )
2412 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2413 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2414 workElements = & copyElements;
2415 //makeWalls = false;
2418 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2419 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2421 ::SMESH_MeshEditor::PGroupIDs groupIds =
2422 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2423 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2425 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2427 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2429 SMESH_CATCH( SMESH::throwCorbaException );
2433 //=======================================================================
2434 //function : RotationSweep
2436 //=======================================================================
2438 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2439 const SMESH::AxisStruct & theAxis,
2440 CORBA::Double theAngleInRadians,
2441 CORBA::Long theNbOfSteps,
2442 CORBA::Double theTolerance)
2443 throw (SALOME::SALOME_Exception)
2445 if ( !myIsPreviewMode ) {
2446 TPythonDump() << this << ".RotationSweep( "
2447 << theIDsOfElements << ", "
2449 << TVar( theAngleInRadians ) << ", "
2450 << TVar( theNbOfSteps ) << ", "
2451 << TVar( theTolerance ) << " )";
2453 rotationSweep(theIDsOfElements,
2461 //=======================================================================
2462 //function : RotationSweepMakeGroups
2464 //=======================================================================
2466 SMESH::ListOfGroups*
2467 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2468 const SMESH::AxisStruct& theAxis,
2469 CORBA::Double theAngleInRadians,
2470 CORBA::Long theNbOfSteps,
2471 CORBA::Double theTolerance)
2472 throw (SALOME::SALOME_Exception)
2474 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2476 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2482 if (!myIsPreviewMode) {
2483 dumpGroupsList(aPythonDump, aGroups);
2484 aPythonDump << this << ".RotationSweepMakeGroups( "
2485 << theIDsOfElements << ", "
2487 << TVar( theAngleInRadians ) << ", "
2488 << TVar( theNbOfSteps ) << ", "
2489 << TVar( theTolerance ) << " )";
2494 //=======================================================================
2495 //function : RotationSweepObject
2497 //=======================================================================
2499 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2500 const SMESH::AxisStruct & theAxis,
2501 CORBA::Double theAngleInRadians,
2502 CORBA::Long theNbOfSteps,
2503 CORBA::Double theTolerance)
2504 throw (SALOME::SALOME_Exception)
2506 if ( !myIsPreviewMode ) {
2507 TPythonDump() << this << ".RotationSweepObject( "
2508 << theObject << ", "
2510 << theAngleInRadians << ", "
2511 << theNbOfSteps << ", "
2512 << theTolerance << " )";
2514 prepareIdSource( theObject );
2515 SMESH::long_array_var anElementsId = theObject->GetIDs();
2516 rotationSweep(anElementsId,
2524 //=======================================================================
2525 //function : RotationSweepObject1D
2527 //=======================================================================
2529 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2530 const SMESH::AxisStruct & theAxis,
2531 CORBA::Double theAngleInRadians,
2532 CORBA::Long theNbOfSteps,
2533 CORBA::Double theTolerance)
2534 throw (SALOME::SALOME_Exception)
2536 if ( !myIsPreviewMode ) {
2537 TPythonDump() << this << ".RotationSweepObject1D( "
2538 << theObject << ", "
2540 << TVar( theAngleInRadians ) << ", "
2541 << TVar( theNbOfSteps ) << ", "
2542 << TVar( theTolerance ) << " )";
2544 prepareIdSource( theObject );
2545 SMESH::long_array_var anElementsId = theObject->GetIDs();
2546 rotationSweep(anElementsId,
2555 //=======================================================================
2556 //function : RotationSweepObject2D
2558 //=======================================================================
2560 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2561 const SMESH::AxisStruct & theAxis,
2562 CORBA::Double theAngleInRadians,
2563 CORBA::Long theNbOfSteps,
2564 CORBA::Double theTolerance)
2565 throw (SALOME::SALOME_Exception)
2567 if ( !myIsPreviewMode ) {
2568 TPythonDump() << this << ".RotationSweepObject2D( "
2569 << theObject << ", "
2571 << TVar( theAngleInRadians ) << ", "
2572 << TVar( theNbOfSteps ) << ", "
2573 << TVar( theTolerance ) << " )";
2575 prepareIdSource( theObject );
2576 SMESH::long_array_var anElementsId = theObject->GetIDs();
2577 rotationSweep(anElementsId,
2586 //=======================================================================
2587 //function : RotationSweepObjectMakeGroups
2589 //=======================================================================
2591 SMESH::ListOfGroups*
2592 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2593 const SMESH::AxisStruct& theAxis,
2594 CORBA::Double theAngleInRadians,
2595 CORBA::Long theNbOfSteps,
2596 CORBA::Double theTolerance)
2597 throw (SALOME::SALOME_Exception)
2599 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2601 prepareIdSource( theObject );
2602 SMESH::long_array_var anElementsId = theObject->GetIDs();
2603 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2609 if (!myIsPreviewMode) {
2610 dumpGroupsList(aPythonDump, aGroups);
2611 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2612 << theObject << ", "
2614 << theAngleInRadians << ", "
2615 << theNbOfSteps << ", "
2616 << theTolerance << " )";
2621 //=======================================================================
2622 //function : RotationSweepObject1DMakeGroups
2624 //=======================================================================
2626 SMESH::ListOfGroups*
2627 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2628 const SMESH::AxisStruct& theAxis,
2629 CORBA::Double theAngleInRadians,
2630 CORBA::Long theNbOfSteps,
2631 CORBA::Double theTolerance)
2632 throw (SALOME::SALOME_Exception)
2634 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2636 prepareIdSource( theObject );
2637 SMESH::long_array_var anElementsId = theObject->GetIDs();
2638 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2645 if (!myIsPreviewMode) {
2646 dumpGroupsList(aPythonDump, aGroups);
2647 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2648 << theObject << ", "
2650 << TVar( theAngleInRadians ) << ", "
2651 << TVar( theNbOfSteps ) << ", "
2652 << TVar( theTolerance ) << " )";
2657 //=======================================================================
2658 //function : RotationSweepObject2DMakeGroups
2660 //=======================================================================
2662 SMESH::ListOfGroups*
2663 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2664 const SMESH::AxisStruct& theAxis,
2665 CORBA::Double theAngleInRadians,
2666 CORBA::Long theNbOfSteps,
2667 CORBA::Double theTolerance)
2668 throw (SALOME::SALOME_Exception)
2670 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2672 prepareIdSource( theObject );
2673 SMESH::long_array_var anElementsId = theObject->GetIDs();
2674 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2681 if (!myIsPreviewMode) {
2682 dumpGroupsList(aPythonDump, aGroups);
2683 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2684 << theObject << ", "
2686 << TVar( theAngleInRadians ) << ", "
2687 << TVar( theNbOfSteps ) << ", "
2688 << TVar( theTolerance ) << " )";
2693 namespace MeshEditor_I
2696 * \brief Structure used to pass extrusion parameters to ::SMESH_MeshEditor
2698 struct ExtrusionParams : public ::SMESH_MeshEditor::ExtrusParam
2700 bool myIsExtrusionByNormal;
2702 static int makeFlags( CORBA::Boolean MakeGroups,
2703 CORBA::Boolean ByAverageNormal = false,
2704 CORBA::Boolean UseInputElemsOnly = false,
2705 CORBA::Long Flags = 0,
2706 CORBA::Boolean MakeBoundary = true )
2708 if ( MakeGroups ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS;
2709 if ( ByAverageNormal ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BY_AVG_NORMAL;
2710 if ( UseInputElemsOnly) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY;
2711 if ( MakeBoundary ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BOUNDARY;
2715 ExtrusionParams(const SMESH::DirStruct & theDir,
2716 CORBA::Long theNbOfSteps,
2717 CORBA::Boolean theMakeGroups):
2718 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2722 makeFlags( theMakeGroups )),
2723 myIsExtrusionByNormal( false )
2727 ExtrusionParams(const SMESH::DirStruct & theDir,
2728 CORBA::Long theNbOfSteps,
2729 CORBA::Boolean theMakeGroups,
2730 CORBA::Long theExtrFlags,
2731 CORBA::Double theSewTolerance):
2732 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2736 makeFlags( theMakeGroups, false, false,
2737 theExtrFlags, false ),
2739 myIsExtrusionByNormal( false )
2742 // params for extrusion by normal
2743 ExtrusionParams(CORBA::Double theStepSize,
2744 CORBA::Long theNbOfSteps,
2745 CORBA::Short theDim,
2746 CORBA::Boolean theUseInputElemsOnly,
2747 CORBA::Boolean theByAverageNormal,
2748 CORBA::Boolean theMakeGroups ):
2749 ::SMESH_MeshEditor::ExtrusParam ( theStepSize,
2751 makeFlags( theMakeGroups,
2752 theByAverageNormal, theUseInputElemsOnly ),
2754 myIsExtrusionByNormal( true )
2760 Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS);
2765 //=======================================================================
2766 //function : extrusionSweep
2768 //=======================================================================
2770 SMESH::ListOfGroups*
2771 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2772 MeshEditor_I::ExtrusionParams& theParams,
2773 const SMDSAbs_ElementType theElementType)
2774 throw (SALOME::SALOME_Exception)
2779 TIDSortedElemSet elements, copyElements;
2780 arrayToSet( theIDsOfElements, getMeshDS(), elements, theElementType );
2782 TIDSortedElemSet* workElements = & elements;
2784 if ( myIsPreviewMode )
2786 SMDSAbs_ElementType previewType = SMDSAbs_Face;
2787 if (theElementType == SMDSAbs_Node)
2788 previewType = SMDSAbs_Edge;
2790 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2791 getPreviewMesh( previewType )->Copy( elements, copyElements, select, avoid );
2792 workElements = & copyElements;
2793 theParams.SetNoGroups();
2795 if ( theParams.myIsExtrusionByNormal && !theParams.ToUseInpElemsOnly() )
2797 TIDSortedElemSet elemsAround, elemsAroundCopy;
2798 getElementsAround( elements, getMeshDS(), elemsAround );
2799 getPreviewMesh( previewType )->Copy( elemsAround, elemsAroundCopy, select, avoid );
2803 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2804 ::SMESH_MeshEditor::PGroupIDs groupIds =
2805 getEditor().ExtrusionSweep (*workElements, theParams, aHystory );
2807 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2809 return theParams.ToMakeGroups() ? getGroups(groupIds.get()) : 0;
2811 SMESH_CATCH( SMESH::throwCorbaException );
2815 //=======================================================================
2816 //function : ExtrusionSweep
2818 //=======================================================================
2820 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2821 const SMESH::DirStruct & theStepVector,
2822 CORBA::Long theNbOfSteps)
2823 throw (SALOME::SALOME_Exception)
2825 ExtrusionParams params( theStepVector, theNbOfSteps, false );
2826 extrusionSweep( theIDsOfElements, params );
2827 if (!myIsPreviewMode) {
2828 TPythonDump() << this << ".ExtrusionSweep( "
2829 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2833 //=======================================================================
2834 //function : ExtrusionSweep0D
2836 //=======================================================================
2838 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2839 const SMESH::DirStruct & theStepVector,
2840 CORBA::Long theNbOfSteps)
2841 throw (SALOME::SALOME_Exception)
2843 ExtrusionParams params( theStepVector, theNbOfSteps, false );
2844 extrusionSweep( theIDsOfElements, params, SMDSAbs_Node );
2845 if (!myIsPreviewMode) {
2846 TPythonDump() << this << ".ExtrusionSweep0D( "
2847 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2851 //=======================================================================
2852 //function : ExtrusionSweepObject
2854 //=======================================================================
2856 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2857 const SMESH::DirStruct & theStepVector,
2858 CORBA::Long theNbOfSteps)
2859 throw (SALOME::SALOME_Exception)
2861 prepareIdSource( theObject );
2862 SMESH::long_array_var anElementsId = theObject->GetIDs();
2863 ExtrusionParams params( theStepVector, theNbOfSteps, false );
2864 extrusionSweep( anElementsId, params );
2865 if (!myIsPreviewMode) {
2866 TPythonDump() << this << ".ExtrusionSweepObject( "
2867 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2871 //=======================================================================
2872 //function : ExtrusionSweepObject0D
2874 //=======================================================================
2876 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2877 const SMESH::DirStruct & theStepVector,
2878 CORBA::Long theNbOfSteps)
2879 throw (SALOME::SALOME_Exception)
2881 prepareIdSource( theObject );
2882 SMESH::long_array_var anElementsId = theObject->GetIDs();
2883 if ( anElementsId->length() == 0 )
2884 if ( SMESH_Mesh_i* mesh = SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
2885 anElementsId = mesh->GetNodesId();
2887 ExtrusionParams params( theStepVector, theNbOfSteps, false );
2888 extrusionSweep( anElementsId, params, SMDSAbs_Node );
2889 if ( !myIsPreviewMode ) {
2890 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2891 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2895 //=======================================================================
2896 //function : ExtrusionSweepObject1D
2898 //=======================================================================
2900 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2901 const SMESH::DirStruct & theStepVector,
2902 CORBA::Long theNbOfSteps)
2903 throw (SALOME::SALOME_Exception)
2905 prepareIdSource( theObject );
2906 SMESH::long_array_var anElementsId = theObject->GetIDs();
2907 ExtrusionParams params( theStepVector, theNbOfSteps, false );
2908 extrusionSweep( anElementsId, params, SMDSAbs_Edge );
2909 if ( !myIsPreviewMode ) {
2910 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2911 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2915 //=======================================================================
2916 //function : ExtrusionSweepObject2D
2918 //=======================================================================
2920 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2921 const SMESH::DirStruct & theStepVector,
2922 CORBA::Long theNbOfSteps)
2923 throw (SALOME::SALOME_Exception)
2925 prepareIdSource( theObject );
2926 SMESH::long_array_var anElementsId = theObject->GetIDs();
2927 ExtrusionParams params( theStepVector, theNbOfSteps, false );
2928 extrusionSweep( anElementsId, params, SMDSAbs_Face );
2929 if ( !myIsPreviewMode ) {
2930 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2931 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2935 //=======================================================================
2936 //function : ExtrusionSweepMakeGroups
2938 //=======================================================================
2940 SMESH::ListOfGroups*
2941 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2942 const SMESH::DirStruct& theStepVector,
2943 CORBA::Long theNbOfSteps)
2944 throw (SALOME::SALOME_Exception)
2946 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2948 ExtrusionParams params( theStepVector, theNbOfSteps, true );
2949 SMESH::ListOfGroups* aGroups = extrusionSweep( theIDsOfElements, params );
2951 if (!myIsPreviewMode) {
2952 dumpGroupsList(aPythonDump, aGroups);
2953 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2954 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2959 //=======================================================================
2960 //function : ExtrusionSweepMakeGroups0D
2962 //=======================================================================
2964 SMESH::ListOfGroups*
2965 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2966 const SMESH::DirStruct& theStepVector,
2967 CORBA::Long theNbOfSteps)
2968 throw (SALOME::SALOME_Exception)
2970 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2972 ExtrusionParams params( theStepVector, theNbOfSteps, true );
2973 SMESH::ListOfGroups* aGroups = extrusionSweep( theIDsOfElements, params, SMDSAbs_Node );
2975 if (!myIsPreviewMode) {
2976 dumpGroupsList(aPythonDump, aGroups);
2977 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2978 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2983 //=======================================================================
2984 //function : ExtrusionSweepObjectMakeGroups
2986 //=======================================================================
2988 SMESH::ListOfGroups*
2989 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2990 const SMESH::DirStruct& theStepVector,
2991 CORBA::Long theNbOfSteps)
2992 throw (SALOME::SALOME_Exception)
2994 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2996 prepareIdSource( theObject );
2997 SMESH::long_array_var anElementsId = theObject->GetIDs();
2998 ExtrusionParams params( theStepVector, theNbOfSteps, true );
2999 SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params );
3001 if (!myIsPreviewMode) {
3002 dumpGroupsList(aPythonDump, aGroups);
3003 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
3004 << ", " << theStepVector << ", " << theNbOfSteps << " )";
3009 //=======================================================================
3010 //function : ExtrusionSweepObject0DMakeGroups
3012 //=======================================================================
3014 SMESH::ListOfGroups*
3015 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3016 const SMESH::DirStruct& theStepVector,
3017 CORBA::Long theNbOfSteps)
3018 throw (SALOME::SALOME_Exception)
3020 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3022 prepareIdSource( theObject );
3023 SMESH::long_array_var anElementsId = theObject->GetIDs();
3024 ExtrusionParams params( theStepVector, theNbOfSteps, true );
3025 SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params, SMDSAbs_Node );
3027 if (!myIsPreviewMode) {
3028 dumpGroupsList(aPythonDump, aGroups);
3029 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
3030 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
3035 //=======================================================================
3036 //function : ExtrusionSweepObject1DMakeGroups
3038 //=======================================================================
3040 SMESH::ListOfGroups*
3041 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3042 const SMESH::DirStruct& theStepVector,
3043 CORBA::Long theNbOfSteps)
3044 throw (SALOME::SALOME_Exception)
3046 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3048 prepareIdSource( theObject );
3049 SMESH::long_array_var anElementsId = theObject->GetIDs();
3050 ExtrusionParams params( theStepVector, theNbOfSteps, true );
3051 SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params, SMDSAbs_Edge );
3053 if (!myIsPreviewMode) {
3054 dumpGroupsList(aPythonDump, aGroups);
3055 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
3056 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
3061 //=======================================================================
3062 //function : ExtrusionSweepObject2DMakeGroups
3064 //=======================================================================
3066 SMESH::ListOfGroups*
3067 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3068 const SMESH::DirStruct& theStepVector,
3069 CORBA::Long theNbOfSteps)
3070 throw (SALOME::SALOME_Exception)
3072 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3074 prepareIdSource( theObject );
3075 SMESH::long_array_var anElementsId = theObject->GetIDs();
3076 ExtrusionParams params( theStepVector, theNbOfSteps, true );
3077 SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params, SMDSAbs_Face );
3079 if (!myIsPreviewMode) {
3080 dumpGroupsList(aPythonDump, aGroups);
3081 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
3082 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
3087 //=======================================================================
3088 //function : ExtrusionByNormal
3090 //=======================================================================
3092 SMESH::ListOfGroups*
3093 SMESH_MeshEditor_i::ExtrusionByNormal(SMESH::SMESH_IDSource_ptr object,
3094 CORBA::Double stepSize,
3095 CORBA::Long nbOfSteps,
3096 CORBA::Boolean byAverageNormal,
3097 CORBA::Boolean useInputElemsOnly,
3098 CORBA::Boolean makeGroups,
3100 throw (SALOME::SALOME_Exception)
3102 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3104 ExtrusionParams params( stepSize, nbOfSteps, dim,
3105 byAverageNormal, useInputElemsOnly, makeGroups );
3107 SMDSAbs_ElementType elemType = ( dim == 1 ? SMDSAbs_Edge : SMDSAbs_Face );
3108 if ( !SMESH::DownCast<SMESH_Mesh_i*>( object ))
3110 SMESH::array_of_ElementType_var elemTypes = object->GetTypes();
3111 if (( elemTypes->length() == 1 ) &&
3112 ( elemTypes[0] == SMESH::EDGE || elemTypes[0] == SMESH::FACE ))
3113 elemType = ( SMDSAbs_ElementType ) elemTypes[0];
3115 prepareIdSource( object );
3116 SMESH::long_array_var anElementsId = object->GetIDs();
3117 SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params, elemType );
3119 if (!myIsPreviewMode) {
3120 dumpGroupsList(aPythonDump, aGroups);
3121 aPythonDump << this << ".ExtrusionByNormal( " << object
3122 << ", " << TVar( stepSize )
3123 << ", " << TVar( nbOfSteps )
3124 << ", " << byAverageNormal
3125 << ", " << makeGroups
3129 return aGroups ? aGroups : new SMESH::ListOfGroups;
3132 //=======================================================================
3133 //function : AdvancedExtrusion
3135 //=======================================================================
3137 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
3138 const SMESH::DirStruct & theStepVector,
3139 CORBA::Long theNbOfSteps,
3140 CORBA::Long theExtrFlags,
3141 CORBA::Double theSewTolerance)
3142 throw (SALOME::SALOME_Exception)
3144 ExtrusionParams params( theStepVector, theNbOfSteps, false, theExtrFlags, theSewTolerance);
3145 extrusionSweep( theIDsOfElements, params );
3147 if ( !myIsPreviewMode ) {
3148 TPythonDump() << "stepVector = " << theStepVector;
3149 TPythonDump() << this << ".AdvancedExtrusion("
3152 << theNbOfSteps << ","
3153 << theExtrFlags << ", "
3154 << theSewTolerance << " )";
3158 //=======================================================================
3159 //function : AdvancedExtrusionMakeGroups
3161 //=======================================================================
3162 SMESH::ListOfGroups*
3163 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
3164 const SMESH::DirStruct& theStepVector,
3165 CORBA::Long theNbOfSteps,
3166 CORBA::Long theExtrFlags,
3167 CORBA::Double theSewTolerance)
3168 throw (SALOME::SALOME_Exception)
3170 if (!myIsPreviewMode) {
3171 TPythonDump() << "stepVector = " << theStepVector;
3173 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3175 ExtrusionParams params( theStepVector, theNbOfSteps, true, theExtrFlags, theSewTolerance);
3176 SMESH::ListOfGroups * aGroups = extrusionSweep( theIDsOfElements, params );
3178 if (!myIsPreviewMode) {
3179 dumpGroupsList(aPythonDump, aGroups);
3180 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
3183 << theNbOfSteps << ","
3184 << theExtrFlags << ", "
3185 << theSewTolerance << " )";
3191 //================================================================================
3193 * \brief Convert extrusion error to IDL enum
3195 //================================================================================
3197 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
3199 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
3203 RETCASE( EXTR_NO_ELEMENTS );
3204 RETCASE( EXTR_PATH_NOT_EDGE );
3205 RETCASE( EXTR_BAD_PATH_SHAPE );
3206 RETCASE( EXTR_BAD_STARTING_NODE );
3207 RETCASE( EXTR_BAD_ANGLES_NUMBER );
3208 RETCASE( EXTR_CANT_GET_TANGENT );
3210 return SMESH::SMESH_MeshEditor::EXTR_OK;
3214 //=======================================================================
3215 //function : extrusionAlongPath
3217 //=======================================================================
3218 SMESH::ListOfGroups*
3219 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3220 SMESH::SMESH_Mesh_ptr thePathMesh,
3221 GEOM::GEOM_Object_ptr thePathShape,
3222 CORBA::Long theNodeStart,
3223 CORBA::Boolean theHasAngles,
3224 const SMESH::double_array & theAngles,
3225 CORBA::Boolean theHasRefPoint,
3226 const SMESH::PointStruct & theRefPoint,
3227 const bool theMakeGroups,
3228 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
3229 const SMDSAbs_ElementType theElementType)
3230 throw (SALOME::SALOME_Exception)
3233 MESSAGE("extrusionAlongPath");
3236 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
3237 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3240 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3242 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3243 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3245 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
3246 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3250 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
3252 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3256 TIDSortedElemSet elements;
3257 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
3259 list<double> angles;
3260 for (int i = 0; i < theAngles.length(); i++) {
3261 angles.push_back( theAngles[i] );
3264 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
3266 int nbOldGroups = myMesh->NbGroup();
3268 ::SMESH_MeshEditor::Extrusion_Error error =
3269 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
3270 theHasAngles, angles, false,
3271 theHasRefPoint, refPnt, theMakeGroups );
3273 declareMeshModified( /*isReComputeSafe=*/true );
3274 theError = convExtrError( error );
3276 if ( theMakeGroups ) {
3277 list<int> groupIDs = myMesh->GetGroupIds();
3278 list<int>::iterator newBegin = groupIDs.begin();
3279 std::advance( newBegin, nbOldGroups ); // skip old groups
3280 groupIDs.erase( groupIDs.begin(), newBegin );
3281 return getGroups( & groupIDs );
3285 SMESH_CATCH( SMESH::throwCorbaException );
3289 //=======================================================================
3290 //function : extrusionAlongPathX
3292 //=======================================================================
3294 SMESH::ListOfGroups*
3295 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
3296 SMESH::SMESH_IDSource_ptr Path,
3297 CORBA::Long NodeStart,
3298 CORBA::Boolean HasAngles,
3299 const SMESH::double_array& Angles,
3300 CORBA::Boolean LinearVariation,
3301 CORBA::Boolean HasRefPoint,
3302 const SMESH::PointStruct& RefPoint,
3304 const SMDSAbs_ElementType ElementType,
3305 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
3306 throw (SALOME::SALOME_Exception)
3309 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
3313 list<double> angles;
3314 for (int i = 0; i < Angles.length(); i++) {
3315 angles.push_back( Angles[i] );
3317 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
3318 int nbOldGroups = myMesh->NbGroup();
3320 if ( Path->_is_nil() ) {
3321 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3325 TIDSortedElemSet elements, copyElements;
3326 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
3328 TIDSortedElemSet* workElements = &elements;
3330 if ( myIsPreviewMode )
3332 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
3333 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
3334 workElements = & copyElements;
3338 ::SMESH_MeshEditor::Extrusion_Error error;
3340 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
3343 SMDS_MeshNode* aNodeStart =
3344 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3345 if ( !aNodeStart ) {
3346 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3349 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
3350 HasAngles, angles, LinearVariation,
3351 HasRefPoint, refPnt, MakeGroups );
3352 declareMeshModified( /*isReComputeSafe=*/true );
3354 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
3357 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
3358 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
3359 SMDS_MeshNode* aNodeStart =
3360 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3361 if ( !aNodeStart ) {
3362 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3365 SMESH_subMesh* aSubMesh =
3366 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
3367 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
3368 HasAngles, angles, LinearVariation,
3369 HasRefPoint, refPnt, MakeGroups );
3370 declareMeshModified( /*isReComputeSafe=*/true );
3372 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
3374 // path as group of 1D elements
3380 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3384 Error = convExtrError( error );
3387 list<int> groupIDs = myMesh->GetGroupIds();
3388 list<int>::iterator newBegin = groupIDs.begin();
3389 std::advance( newBegin, nbOldGroups ); // skip old groups
3390 groupIDs.erase( groupIDs.begin(), newBegin );
3391 return getGroups( & groupIDs );
3395 SMESH_CATCH( SMESH::throwCorbaException );
3399 //=======================================================================
3400 //function : ExtrusionAlongPath
3402 //=======================================================================
3404 SMESH::SMESH_MeshEditor::Extrusion_Error
3405 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3406 SMESH::SMESH_Mesh_ptr thePathMesh,
3407 GEOM::GEOM_Object_ptr thePathShape,
3408 CORBA::Long theNodeStart,
3409 CORBA::Boolean theHasAngles,
3410 const SMESH::double_array & theAngles,
3411 CORBA::Boolean theHasRefPoint,
3412 const SMESH::PointStruct & theRefPoint)
3413 throw (SALOME::SALOME_Exception)
3415 MESSAGE("ExtrusionAlongPath");
3416 if ( !myIsPreviewMode ) {
3417 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
3418 << theIDsOfElements << ", "
3419 << thePathMesh << ", "
3420 << thePathShape << ", "
3421 << theNodeStart << ", "
3422 << theHasAngles << ", "
3423 << theAngles << ", "
3424 << theHasRefPoint << ", "
3425 << "SMESH.PointStruct( "
3426 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3427 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3428 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3430 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3431 extrusionAlongPath( theIDsOfElements,
3444 //=======================================================================
3445 //function : ExtrusionAlongPathObject
3447 //=======================================================================
3449 SMESH::SMESH_MeshEditor::Extrusion_Error
3450 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
3451 SMESH::SMESH_Mesh_ptr thePathMesh,
3452 GEOM::GEOM_Object_ptr thePathShape,
3453 CORBA::Long theNodeStart,
3454 CORBA::Boolean theHasAngles,
3455 const SMESH::double_array & theAngles,
3456 CORBA::Boolean theHasRefPoint,
3457 const SMESH::PointStruct & theRefPoint)
3458 throw (SALOME::SALOME_Exception)
3460 if ( !myIsPreviewMode ) {
3461 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
3462 << theObject << ", "
3463 << thePathMesh << ", "
3464 << thePathShape << ", "
3465 << theNodeStart << ", "
3466 << theHasAngles << ", "
3467 << theAngles << ", "
3468 << theHasRefPoint << ", "
3469 << "SMESH.PointStruct( "
3470 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3471 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3472 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3474 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3475 prepareIdSource( theObject );
3476 SMESH::long_array_var anElementsId = theObject->GetIDs();
3477 extrusionAlongPath( anElementsId,
3490 //=======================================================================
3491 //function : ExtrusionAlongPathObject1D
3493 //=======================================================================
3495 SMESH::SMESH_MeshEditor::Extrusion_Error
3496 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
3497 SMESH::SMESH_Mesh_ptr thePathMesh,
3498 GEOM::GEOM_Object_ptr thePathShape,
3499 CORBA::Long theNodeStart,
3500 CORBA::Boolean theHasAngles,
3501 const SMESH::double_array & theAngles,
3502 CORBA::Boolean theHasRefPoint,
3503 const SMESH::PointStruct & theRefPoint)
3504 throw (SALOME::SALOME_Exception)
3506 if ( !myIsPreviewMode ) {
3507 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
3508 << theObject << ", "
3509 << thePathMesh << ", "
3510 << thePathShape << ", "
3511 << theNodeStart << ", "
3512 << theHasAngles << ", "
3513 << theAngles << ", "
3514 << theHasRefPoint << ", "
3515 << "SMESH.PointStruct( "
3516 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3517 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3518 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3520 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3521 prepareIdSource( theObject );
3522 SMESH::long_array_var anElementsId = theObject->GetIDs();
3523 extrusionAlongPath( anElementsId,
3537 //=======================================================================
3538 //function : ExtrusionAlongPathObject2D
3540 //=======================================================================
3542 SMESH::SMESH_MeshEditor::Extrusion_Error
3543 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3544 SMESH::SMESH_Mesh_ptr thePathMesh,
3545 GEOM::GEOM_Object_ptr thePathShape,
3546 CORBA::Long theNodeStart,
3547 CORBA::Boolean theHasAngles,
3548 const SMESH::double_array & theAngles,
3549 CORBA::Boolean theHasRefPoint,
3550 const SMESH::PointStruct & theRefPoint)
3551 throw (SALOME::SALOME_Exception)
3553 if ( !myIsPreviewMode ) {
3554 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3555 << theObject << ", "
3556 << thePathMesh << ", "
3557 << thePathShape << ", "
3558 << theNodeStart << ", "
3559 << theHasAngles << ", "
3560 << theAngles << ", "
3561 << theHasRefPoint << ", "
3562 << "SMESH.PointStruct( "
3563 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3564 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3565 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3567 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3568 prepareIdSource( theObject );
3569 SMESH::long_array_var anElementsId = theObject->GetIDs();
3570 extrusionAlongPath( anElementsId,
3585 //=======================================================================
3586 //function : ExtrusionAlongPathMakeGroups
3588 //=======================================================================
3590 SMESH::ListOfGroups*
3591 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3592 SMESH::SMESH_Mesh_ptr thePathMesh,
3593 GEOM::GEOM_Object_ptr thePathShape,
3594 CORBA::Long theNodeStart,
3595 CORBA::Boolean theHasAngles,
3596 const SMESH::double_array& theAngles,
3597 CORBA::Boolean theHasRefPoint,
3598 const SMESH::PointStruct& theRefPoint,
3599 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3600 throw (SALOME::SALOME_Exception)
3602 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3604 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3614 if (!myIsPreviewMode) {
3615 bool isDumpGroups = aGroups && aGroups->length() > 0;
3617 aPythonDump << "(" << aGroups << ", error)";
3619 aPythonDump <<"error";
3621 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3622 << theIDsOfElements << ", "
3623 << thePathMesh << ", "
3624 << thePathShape << ", "
3625 << theNodeStart << ", "
3626 << theHasAngles << ", "
3627 << theAngles << ", "
3628 << theHasRefPoint << ", "
3629 << "SMESH.PointStruct( "
3630 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3631 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3632 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3637 //=======================================================================
3638 //function : ExtrusionAlongPathObjectMakeGroups
3640 //=======================================================================
3642 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3643 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3644 SMESH::SMESH_Mesh_ptr thePathMesh,
3645 GEOM::GEOM_Object_ptr thePathShape,
3646 CORBA::Long theNodeStart,
3647 CORBA::Boolean theHasAngles,
3648 const SMESH::double_array& theAngles,
3649 CORBA::Boolean theHasRefPoint,
3650 const SMESH::PointStruct& theRefPoint,
3651 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3652 throw (SALOME::SALOME_Exception)
3654 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3656 prepareIdSource( theObject );
3657 SMESH::long_array_var anElementsId = theObject->GetIDs();
3658 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3669 if (!myIsPreviewMode) {
3670 bool isDumpGroups = aGroups && aGroups->length() > 0;
3672 aPythonDump << "(" << aGroups << ", error)";
3674 aPythonDump <<"error";
3676 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3677 << theObject << ", "
3678 << thePathMesh << ", "
3679 << thePathShape << ", "
3680 << theNodeStart << ", "
3681 << theHasAngles << ", "
3682 << theAngles << ", "
3683 << theHasRefPoint << ", "
3684 << "SMESH.PointStruct( "
3685 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3686 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3687 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3692 //=======================================================================
3693 //function : ExtrusionAlongPathObject1DMakeGroups
3695 //=======================================================================
3697 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3698 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3699 SMESH::SMESH_Mesh_ptr thePathMesh,
3700 GEOM::GEOM_Object_ptr thePathShape,
3701 CORBA::Long theNodeStart,
3702 CORBA::Boolean theHasAngles,
3703 const SMESH::double_array& theAngles,
3704 CORBA::Boolean theHasRefPoint,
3705 const SMESH::PointStruct& theRefPoint,
3706 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3707 throw (SALOME::SALOME_Exception)
3709 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3711 prepareIdSource( theObject );
3712 SMESH::long_array_var anElementsId = theObject->GetIDs();
3713 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3725 if (!myIsPreviewMode) {
3726 bool isDumpGroups = aGroups && aGroups->length() > 0;
3728 aPythonDump << "(" << aGroups << ", error)";
3730 aPythonDump << "error";
3732 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3733 << theObject << ", "
3734 << thePathMesh << ", "
3735 << thePathShape << ", "
3736 << theNodeStart << ", "
3737 << theHasAngles << ", "
3738 << theAngles << ", "
3739 << theHasRefPoint << ", "
3740 << "SMESH.PointStruct( "
3741 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3742 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3743 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3748 //=======================================================================
3749 //function : ExtrusionAlongPathObject2DMakeGroups
3751 //=======================================================================
3753 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3754 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3755 SMESH::SMESH_Mesh_ptr thePathMesh,
3756 GEOM::GEOM_Object_ptr thePathShape,
3757 CORBA::Long theNodeStart,
3758 CORBA::Boolean theHasAngles,
3759 const SMESH::double_array& theAngles,
3760 CORBA::Boolean theHasRefPoint,
3761 const SMESH::PointStruct& theRefPoint,
3762 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3763 throw (SALOME::SALOME_Exception)
3765 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3767 prepareIdSource( theObject );
3768 SMESH::long_array_var anElementsId = theObject->GetIDs();
3769 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3781 if (!myIsPreviewMode) {
3782 bool isDumpGroups = aGroups && aGroups->length() > 0;
3784 aPythonDump << "(" << aGroups << ", error)";
3786 aPythonDump << "error";
3788 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3789 << theObject << ", "
3790 << thePathMesh << ", "
3791 << thePathShape << ", "
3792 << theNodeStart << ", "
3793 << theHasAngles << ", "
3794 << theAngles << ", "
3795 << theHasRefPoint << ", "
3796 << "SMESH.PointStruct( "
3797 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3798 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3799 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3804 //=======================================================================
3805 //function : ExtrusionAlongPathObjX
3807 //=======================================================================
3809 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3810 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3811 SMESH::SMESH_IDSource_ptr Path,
3812 CORBA::Long NodeStart,
3813 CORBA::Boolean HasAngles,
3814 const SMESH::double_array& Angles,
3815 CORBA::Boolean LinearVariation,
3816 CORBA::Boolean HasRefPoint,
3817 const SMESH::PointStruct& RefPoint,
3818 CORBA::Boolean MakeGroups,
3819 SMESH::ElementType ElemType,
3820 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3821 throw (SALOME::SALOME_Exception)
3823 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3825 prepareIdSource( Object );
3826 SMESH::long_array_var anElementsId = Object->GetIDs();
3827 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3836 (SMDSAbs_ElementType)ElemType,
3839 if (!myIsPreviewMode) {
3840 bool isDumpGroups = aGroups && aGroups->length() > 0;
3842 aPythonDump << "(" << *aGroups << ", error)";
3844 aPythonDump << "error";
3846 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3849 << NodeStart << ", "
3850 << HasAngles << ", "
3851 << TVar( Angles ) << ", "
3852 << LinearVariation << ", "
3853 << HasRefPoint << ", "
3854 << "SMESH.PointStruct( "
3855 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3856 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3857 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3858 << MakeGroups << ", "
3859 << ElemType << " )";
3864 //=======================================================================
3865 //function : ExtrusionAlongPathX
3867 //=======================================================================
3869 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3870 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3871 SMESH::SMESH_IDSource_ptr Path,
3872 CORBA::Long NodeStart,
3873 CORBA::Boolean HasAngles,
3874 const SMESH::double_array& Angles,
3875 CORBA::Boolean LinearVariation,
3876 CORBA::Boolean HasRefPoint,
3877 const SMESH::PointStruct& RefPoint,
3878 CORBA::Boolean MakeGroups,
3879 SMESH::ElementType ElemType,
3880 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3881 throw (SALOME::SALOME_Exception)
3883 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3885 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3894 (SMDSAbs_ElementType)ElemType,
3897 if (!myIsPreviewMode) {
3898 bool isDumpGroups = aGroups && aGroups->length() > 0;
3900 aPythonDump << "(" << *aGroups << ", error)";
3902 aPythonDump <<"error";
3904 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3905 << IDsOfElements << ", "
3907 << NodeStart << ", "
3908 << HasAngles << ", "
3909 << TVar( Angles ) << ", "
3910 << LinearVariation << ", "
3911 << HasRefPoint << ", "
3912 << "SMESH.PointStruct( "
3913 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3914 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3915 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3916 << MakeGroups << ", "
3917 << ElemType << " )";
3922 //================================================================================
3924 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3925 * of given angles along path steps
3926 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3927 * which proceeds the extrusion
3928 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3929 * is used to define the sub-mesh for the path
3931 //================================================================================
3933 SMESH::double_array*
3934 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3935 GEOM::GEOM_Object_ptr thePathShape,
3936 const SMESH::double_array & theAngles)
3938 SMESH::double_array_var aResult = new SMESH::double_array();
3939 int nbAngles = theAngles.length();
3940 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3942 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3943 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3944 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3945 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3946 return aResult._retn();
3947 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3948 if ( nbSteps == nbAngles )
3950 aResult.inout() = theAngles;
3954 aResult->length( nbSteps );
3955 double rAn2St = double( nbAngles ) / double( nbSteps );
3956 double angPrev = 0, angle;
3957 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3959 double angCur = rAn2St * ( iSt+1 );
3960 double angCurFloor = floor( angCur );
3961 double angPrevFloor = floor( angPrev );
3962 if ( angPrevFloor == angCurFloor )
3963 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3966 int iP = int( angPrevFloor );
3967 double angPrevCeil = ceil(angPrev);
3968 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3970 int iC = int( angCurFloor );
3971 if ( iC < nbAngles )
3972 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3974 iP = int( angPrevCeil );
3976 angle += theAngles[ iC ];
3978 aResult[ iSt ] = angle;
3983 // Update Python script
3984 TPythonDump() << "rotAngles = " << theAngles;
3985 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3986 << thePathMesh << ", "
3987 << thePathShape << ", "
3990 return aResult._retn();
3993 //=======================================================================
3996 //=======================================================================
3998 SMESH::ListOfGroups*
3999 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
4000 const SMESH::AxisStruct & theAxis,
4001 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4002 CORBA::Boolean theCopy,
4004 ::SMESH_Mesh* theTargetMesh)
4005 throw (SALOME::SALOME_Exception)
4010 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
4011 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
4013 if ( theTargetMesh )
4017 switch ( theMirrorType ) {
4018 case SMESH::SMESH_MeshEditor::POINT:
4019 aTrsf.SetMirror( P );
4021 case SMESH::SMESH_MeshEditor::AXIS:
4022 aTrsf.SetMirror( gp_Ax1( P, V ));
4025 aTrsf.SetMirror( gp_Ax2( P, V ));
4028 TIDSortedElemSet copyElements;
4029 TIDSortedElemSet* workElements = & theElements;
4031 if ( myIsPreviewMode )
4033 TPreviewMesh * tmpMesh = getPreviewMesh();
4034 tmpMesh->Copy( theElements, copyElements);
4035 if ( !theCopy && !theTargetMesh )
4037 TIDSortedElemSet elemsAround, elemsAroundCopy;
4038 getElementsAround( theElements, getMeshDS(), elemsAround );
4039 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4041 workElements = & copyElements;
4042 theMakeGroups = false;
4045 ::SMESH_MeshEditor::PGroupIDs groupIds =
4046 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4048 if ( theCopy && !myIsPreviewMode)
4050 if ( theTargetMesh )
4052 theTargetMesh->GetMeshDS()->Modified();
4056 declareMeshModified( /*isReComputeSafe=*/false );
4059 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4061 SMESH_CATCH( SMESH::throwCorbaException );
4065 //=======================================================================
4068 //=======================================================================
4070 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
4071 const SMESH::AxisStruct & theAxis,
4072 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4073 CORBA::Boolean theCopy)
4074 throw (SALOME::SALOME_Exception)
4076 if ( !myIsPreviewMode ) {
4077 TPythonDump() << this << ".Mirror( "
4078 << theIDsOfElements << ", "
4080 << mirrorTypeName(theMirrorType) << ", "
4083 if ( theIDsOfElements.length() > 0 )
4085 TIDSortedElemSet elements;
4086 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4087 mirror(elements, theAxis, theMirrorType, theCopy, false);
4092 //=======================================================================
4093 //function : MirrorObject
4095 //=======================================================================
4097 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
4098 const SMESH::AxisStruct & theAxis,
4099 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4100 CORBA::Boolean theCopy)
4101 throw (SALOME::SALOME_Exception)
4103 if ( !myIsPreviewMode ) {
4104 TPythonDump() << this << ".MirrorObject( "
4105 << theObject << ", "
4107 << mirrorTypeName(theMirrorType) << ", "
4110 TIDSortedElemSet elements;
4112 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4114 prepareIdSource( theObject );
4115 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4116 mirror(elements, theAxis, theMirrorType, theCopy, false);
4119 //=======================================================================
4120 //function : MirrorMakeGroups
4122 //=======================================================================
4124 SMESH::ListOfGroups*
4125 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
4126 const SMESH::AxisStruct& theMirror,
4127 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
4128 throw (SALOME::SALOME_Exception)
4130 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4132 SMESH::ListOfGroups * aGroups = 0;
4133 if ( theIDsOfElements.length() > 0 )
4135 TIDSortedElemSet elements;
4136 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4137 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
4139 if (!myIsPreviewMode) {
4140 dumpGroupsList(aPythonDump, aGroups);
4141 aPythonDump << this << ".MirrorMakeGroups( "
4142 << theIDsOfElements << ", "
4143 << theMirror << ", "
4144 << mirrorTypeName(theMirrorType) << " )";
4149 //=======================================================================
4150 //function : MirrorObjectMakeGroups
4152 //=======================================================================
4154 SMESH::ListOfGroups*
4155 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4156 const SMESH::AxisStruct& theMirror,
4157 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
4158 throw (SALOME::SALOME_Exception)
4160 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4162 SMESH::ListOfGroups * aGroups = 0;
4163 TIDSortedElemSet elements;
4164 prepareIdSource( theObject );
4165 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4166 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
4168 if (!myIsPreviewMode)
4170 dumpGroupsList(aPythonDump,aGroups);
4171 aPythonDump << this << ".MirrorObjectMakeGroups( "
4172 << theObject << ", "
4173 << theMirror << ", "
4174 << mirrorTypeName(theMirrorType) << " )";
4179 //=======================================================================
4180 //function : MirrorMakeMesh
4182 //=======================================================================
4184 SMESH::SMESH_Mesh_ptr
4185 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
4186 const SMESH::AxisStruct& theMirror,
4187 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4188 CORBA::Boolean theCopyGroups,
4189 const char* theMeshName)
4190 throw (SALOME::SALOME_Exception)
4192 SMESH_Mesh_i* mesh_i;
4193 SMESH::SMESH_Mesh_var mesh;
4194 { // open new scope to dump "MakeMesh" command
4195 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4197 TPythonDump pydump; // to prevent dump at mesh creation
4199 mesh = makeMesh( theMeshName );
4200 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4201 if (mesh_i && theIDsOfElements.length() > 0 )
4203 TIDSortedElemSet elements;
4204 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4205 mirror(elements, theMirror, theMirrorType,
4206 false, theCopyGroups, & mesh_i->GetImpl());
4207 mesh_i->CreateGroupServants();
4210 if (!myIsPreviewMode) {
4211 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
4212 << theIDsOfElements << ", "
4213 << theMirror << ", "
4214 << mirrorTypeName(theMirrorType) << ", "
4215 << theCopyGroups << ", '"
4216 << theMeshName << "' )";
4221 if (!myIsPreviewMode && mesh_i)
4222 mesh_i->GetGroups();
4224 return mesh._retn();
4227 //=======================================================================
4228 //function : MirrorObjectMakeMesh
4230 //=======================================================================
4232 SMESH::SMESH_Mesh_ptr
4233 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4234 const SMESH::AxisStruct& theMirror,
4235 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4236 CORBA::Boolean theCopyGroups,
4237 const char* theMeshName)
4238 throw (SALOME::SALOME_Exception)
4240 SMESH_Mesh_i* mesh_i;
4241 SMESH::SMESH_Mesh_var mesh;
4242 { // open new scope to dump "MakeMesh" command
4243 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4245 TPythonDump pydump; // to prevent dump at mesh creation
4247 mesh = makeMesh( theMeshName );
4248 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4249 TIDSortedElemSet elements;
4250 prepareIdSource( theObject );
4252 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4254 mirror(elements, theMirror, theMirrorType,
4255 false, theCopyGroups, & mesh_i->GetImpl());
4256 mesh_i->CreateGroupServants();
4258 if (!myIsPreviewMode) {
4259 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
4260 << theObject << ", "
4261 << theMirror << ", "
4262 << mirrorTypeName(theMirrorType) << ", "
4263 << theCopyGroups << ", '"
4264 << theMeshName << "' )";
4269 if (!myIsPreviewMode && mesh_i)
4270 mesh_i->GetGroups();
4272 return mesh._retn();
4275 //=======================================================================
4276 //function : translate
4278 //=======================================================================
4280 SMESH::ListOfGroups*
4281 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
4282 const SMESH::DirStruct & theVector,
4283 CORBA::Boolean theCopy,
4285 ::SMESH_Mesh* theTargetMesh)
4286 throw (SALOME::SALOME_Exception)
4291 if ( theTargetMesh )
4295 const SMESH::PointStruct * P = &theVector.PS;
4296 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
4298 TIDSortedElemSet copyElements;
4299 TIDSortedElemSet* workElements = &theElements;
4301 if ( myIsPreviewMode )
4303 TPreviewMesh * tmpMesh = getPreviewMesh();
4304 tmpMesh->Copy( theElements, copyElements);
4305 if ( !theCopy && !theTargetMesh )
4307 TIDSortedElemSet elemsAround, elemsAroundCopy;
4308 getElementsAround( theElements, getMeshDS(), elemsAround );
4309 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4311 workElements = & copyElements;
4312 theMakeGroups = false;
4315 ::SMESH_MeshEditor::PGroupIDs groupIds =
4316 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4318 if ( theCopy && !myIsPreviewMode )
4320 if ( theTargetMesh )
4322 theTargetMesh->GetMeshDS()->Modified();
4326 declareMeshModified( /*isReComputeSafe=*/false );
4330 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4332 SMESH_CATCH( SMESH::throwCorbaException );
4336 //=======================================================================
4337 //function : Translate
4339 //=======================================================================
4341 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
4342 const SMESH::DirStruct & theVector,
4343 CORBA::Boolean theCopy)
4344 throw (SALOME::SALOME_Exception)
4346 if (!myIsPreviewMode) {
4347 TPythonDump() << this << ".Translate( "
4348 << theIDsOfElements << ", "
4349 << theVector << ", "
4352 if (theIDsOfElements.length()) {
4353 TIDSortedElemSet elements;
4354 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4355 translate(elements, theVector, theCopy, false);
4359 //=======================================================================
4360 //function : TranslateObject
4362 //=======================================================================
4364 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
4365 const SMESH::DirStruct & theVector,
4366 CORBA::Boolean theCopy)
4367 throw (SALOME::SALOME_Exception)
4369 if (!myIsPreviewMode) {
4370 TPythonDump() << this << ".TranslateObject( "
4371 << theObject << ", "
4372 << theVector << ", "
4375 TIDSortedElemSet elements;
4377 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4379 prepareIdSource( theObject );
4380 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4381 translate(elements, theVector, theCopy, false);
4384 //=======================================================================
4385 //function : TranslateMakeGroups
4387 //=======================================================================
4389 SMESH::ListOfGroups*
4390 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
4391 const SMESH::DirStruct& theVector)
4392 throw (SALOME::SALOME_Exception)
4394 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4396 SMESH::ListOfGroups * aGroups = 0;
4397 if (theIDsOfElements.length()) {
4398 TIDSortedElemSet elements;
4399 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4400 aGroups = translate(elements,theVector,true,true);
4402 if (!myIsPreviewMode) {
4403 dumpGroupsList(aPythonDump, aGroups);
4404 aPythonDump << this << ".TranslateMakeGroups( "
4405 << theIDsOfElements << ", "
4406 << theVector << " )";
4411 //=======================================================================
4412 //function : TranslateObjectMakeGroups
4414 //=======================================================================
4416 SMESH::ListOfGroups*
4417 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4418 const SMESH::DirStruct& theVector)
4419 throw (SALOME::SALOME_Exception)
4421 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4423 SMESH::ListOfGroups * aGroups = 0;
4424 TIDSortedElemSet elements;
4425 prepareIdSource( theObject );
4426 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4427 aGroups = translate(elements, theVector, true, true);
4429 if (!myIsPreviewMode) {
4430 dumpGroupsList(aPythonDump, aGroups);
4431 aPythonDump << this << ".TranslateObjectMakeGroups( "
4432 << theObject << ", "
4433 << theVector << " )";
4438 //=======================================================================
4439 //function : TranslateMakeMesh
4441 //=======================================================================
4443 SMESH::SMESH_Mesh_ptr
4444 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
4445 const SMESH::DirStruct& theVector,
4446 CORBA::Boolean theCopyGroups,
4447 const char* theMeshName)
4448 throw (SALOME::SALOME_Exception)
4450 SMESH_Mesh_i* mesh_i;
4451 SMESH::SMESH_Mesh_var mesh;
4453 { // open new scope to dump "MakeMesh" command
4454 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4456 TPythonDump pydump; // to prevent dump at mesh creation
4458 mesh = makeMesh( theMeshName );
4459 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4461 if ( mesh_i && theIDsOfElements.length() )
4463 TIDSortedElemSet elements;
4464 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4465 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
4466 mesh_i->CreateGroupServants();
4469 if ( !myIsPreviewMode ) {
4470 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
4471 << theIDsOfElements << ", "
4472 << theVector << ", "
4473 << theCopyGroups << ", '"
4474 << theMeshName << "' )";
4479 if (!myIsPreviewMode && mesh_i)
4480 mesh_i->GetGroups();
4482 return mesh._retn();
4485 //=======================================================================
4486 //function : TranslateObjectMakeMesh
4488 //=======================================================================
4490 SMESH::SMESH_Mesh_ptr
4491 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4492 const SMESH::DirStruct& theVector,
4493 CORBA::Boolean theCopyGroups,
4494 const char* theMeshName)
4495 throw (SALOME::SALOME_Exception)
4498 SMESH_Mesh_i* mesh_i;
4499 SMESH::SMESH_Mesh_var mesh;
4500 { // open new scope to dump "MakeMesh" command
4501 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4503 TPythonDump pydump; // to prevent dump at mesh creation
4504 mesh = makeMesh( theMeshName );
4505 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4507 TIDSortedElemSet elements;
4508 prepareIdSource( theObject );
4510 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4512 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
4513 mesh_i->CreateGroupServants();
4515 if ( !myIsPreviewMode ) {
4516 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
4517 << theObject << ", "
4518 << theVector << ", "
4519 << theCopyGroups << ", '"
4520 << theMeshName << "' )";
4525 if (!myIsPreviewMode && mesh_i)
4526 mesh_i->GetGroups();
4528 return mesh._retn();
4530 SMESH_CATCH( SMESH::throwCorbaException );
4534 //=======================================================================
4537 //=======================================================================
4539 SMESH::ListOfGroups*
4540 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
4541 const SMESH::AxisStruct & theAxis,
4542 CORBA::Double theAngle,
4543 CORBA::Boolean theCopy,
4545 ::SMESH_Mesh* theTargetMesh)
4546 throw (SALOME::SALOME_Exception)
4551 if ( theTargetMesh )
4554 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
4555 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
4558 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
4560 TIDSortedElemSet copyElements;
4561 TIDSortedElemSet* workElements = &theElements;
4562 if ( myIsPreviewMode ) {
4563 TPreviewMesh * tmpMesh = getPreviewMesh();
4564 tmpMesh->Copy( theElements, copyElements );
4565 if ( !theCopy && !theTargetMesh )
4567 TIDSortedElemSet elemsAround, elemsAroundCopy;
4568 getElementsAround( theElements, getMeshDS(), elemsAround );
4569 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4571 workElements = ©Elements;
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 );
4584 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4586 SMESH_CATCH( SMESH::throwCorbaException );
4590 //=======================================================================
4593 //=======================================================================
4595 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4596 const SMESH::AxisStruct & theAxis,
4597 CORBA::Double theAngle,
4598 CORBA::Boolean theCopy)
4599 throw (SALOME::SALOME_Exception)
4601 if (!myIsPreviewMode) {
4602 TPythonDump() << this << ".Rotate( "
4603 << theIDsOfElements << ", "
4605 << TVar( theAngle ) << ", "
4608 if (theIDsOfElements.length() > 0)
4610 TIDSortedElemSet elements;
4611 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4612 rotate(elements,theAxis,theAngle,theCopy,false);
4616 //=======================================================================
4617 //function : RotateObject
4619 //=======================================================================
4621 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4622 const SMESH::AxisStruct & theAxis,
4623 CORBA::Double theAngle,
4624 CORBA::Boolean theCopy)
4625 throw (SALOME::SALOME_Exception)
4627 if ( !myIsPreviewMode ) {
4628 TPythonDump() << this << ".RotateObject( "
4629 << theObject << ", "
4631 << TVar( theAngle ) << ", "
4634 TIDSortedElemSet elements;
4635 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4636 prepareIdSource( theObject );
4637 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4638 rotate(elements,theAxis,theAngle,theCopy,false);
4641 //=======================================================================
4642 //function : RotateMakeGroups
4644 //=======================================================================
4646 SMESH::ListOfGroups*
4647 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4648 const SMESH::AxisStruct& theAxis,
4649 CORBA::Double theAngle)
4650 throw (SALOME::SALOME_Exception)
4652 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4654 SMESH::ListOfGroups * aGroups = 0;
4655 if (theIDsOfElements.length() > 0)
4657 TIDSortedElemSet elements;
4658 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4659 aGroups = rotate(elements,theAxis,theAngle,true,true);
4661 if (!myIsPreviewMode) {
4662 dumpGroupsList(aPythonDump, aGroups);
4663 aPythonDump << this << ".RotateMakeGroups( "
4664 << theIDsOfElements << ", "
4666 << TVar( theAngle ) << " )";
4671 //=======================================================================
4672 //function : RotateObjectMakeGroups
4674 //=======================================================================
4676 SMESH::ListOfGroups*
4677 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4678 const SMESH::AxisStruct& theAxis,
4679 CORBA::Double theAngle)
4680 throw (SALOME::SALOME_Exception)
4682 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4684 SMESH::ListOfGroups * aGroups = 0;
4685 TIDSortedElemSet elements;
4686 prepareIdSource( theObject );
4687 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4688 aGroups = rotate(elements, theAxis, theAngle, true, true);
4690 if (!myIsPreviewMode) {
4691 dumpGroupsList(aPythonDump, aGroups);
4692 aPythonDump << this << ".RotateObjectMakeGroups( "
4693 << theObject << ", "
4695 << TVar( theAngle ) << " )";
4700 //=======================================================================
4701 //function : RotateMakeMesh
4703 //=======================================================================
4705 SMESH::SMESH_Mesh_ptr
4706 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4707 const SMESH::AxisStruct& theAxis,
4708 CORBA::Double theAngleInRadians,
4709 CORBA::Boolean theCopyGroups,
4710 const char* theMeshName)
4711 throw (SALOME::SALOME_Exception)
4714 SMESH::SMESH_Mesh_var mesh;
4715 SMESH_Mesh_i* mesh_i;
4717 { // open new scope to dump "MakeMesh" command
4718 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4720 TPythonDump pydump; // to prevent dump at mesh creation
4722 mesh = makeMesh( theMeshName );
4723 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4725 if ( mesh_i && theIDsOfElements.length() > 0 )
4727 TIDSortedElemSet elements;
4728 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4729 rotate(elements, theAxis, theAngleInRadians,
4730 false, theCopyGroups, & mesh_i->GetImpl());
4731 mesh_i->CreateGroupServants();
4733 if ( !myIsPreviewMode ) {
4734 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4735 << theIDsOfElements << ", "
4737 << TVar( theAngleInRadians ) << ", "
4738 << theCopyGroups << ", '"
4739 << theMeshName << "' )";
4744 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4745 mesh_i->GetGroups();
4747 return mesh._retn();
4749 SMESH_CATCH( SMESH::throwCorbaException );
4753 //=======================================================================
4754 //function : RotateObjectMakeMesh
4756 //=======================================================================
4758 SMESH::SMESH_Mesh_ptr
4759 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4760 const SMESH::AxisStruct& theAxis,
4761 CORBA::Double theAngleInRadians,
4762 CORBA::Boolean theCopyGroups,
4763 const char* theMeshName)
4764 throw (SALOME::SALOME_Exception)
4767 SMESH::SMESH_Mesh_var mesh;
4768 SMESH_Mesh_i* mesh_i;
4770 {// open new scope to dump "MakeMesh" command
4771 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4773 TPythonDump pydump; // to prevent dump at mesh creation
4774 mesh = makeMesh( theMeshName );
4775 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4777 TIDSortedElemSet elements;
4778 prepareIdSource( theObject );
4780 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4782 rotate(elements, theAxis, theAngleInRadians,
4783 false, theCopyGroups, & mesh_i->GetImpl());
4784 mesh_i->CreateGroupServants();
4786 if ( !myIsPreviewMode ) {
4787 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4788 << theObject << ", "
4790 << TVar( theAngleInRadians ) << ", "
4791 << theCopyGroups << ", '"
4792 << theMeshName << "' )";
4797 if (!myIsPreviewMode && mesh_i)
4798 mesh_i->GetGroups();
4800 return mesh._retn();
4802 SMESH_CATCH( SMESH::throwCorbaException );
4806 //=======================================================================
4809 //=======================================================================
4811 SMESH::ListOfGroups*
4812 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4813 const SMESH::PointStruct& thePoint,
4814 const SMESH::double_array& theScaleFact,
4815 CORBA::Boolean theCopy,
4817 ::SMESH_Mesh* theTargetMesh)
4818 throw (SALOME::SALOME_Exception)
4822 if ( theScaleFact.length() < 1 )
4823 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4824 if ( theScaleFact.length() == 2 )
4825 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4827 if ( theTargetMesh )
4830 TIDSortedElemSet elements;
4831 prepareIdSource( theObject );
4832 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4833 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4838 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4839 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4841 double tol = std::numeric_limits<double>::max();
4844 #if OCC_VERSION_LARGE > 0x06070100
4845 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4846 0, S[1], 0, thePoint.y * (1-S[1]),
4847 0, 0, S[2], thePoint.z * (1-S[2]) );
4849 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4850 0, S[1], 0, thePoint.y * (1-S[1]),
4851 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4854 TIDSortedElemSet copyElements;
4855 TIDSortedElemSet* workElements = &elements;
4856 if ( myIsPreviewMode )
4858 TPreviewMesh * tmpMesh = getPreviewMesh();
4859 tmpMesh->Copy( elements, copyElements);
4860 if ( !theCopy && !theTargetMesh )
4862 TIDSortedElemSet elemsAround, elemsAroundCopy;
4863 getElementsAround( elements, getMeshDS(), elemsAround );
4864 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4866 workElements = & copyElements;
4867 theMakeGroups = false;
4870 ::SMESH_MeshEditor::PGroupIDs groupIds =
4871 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4873 if ( theCopy && !myIsPreviewMode )
4875 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4876 else declareMeshModified( /*isReComputeSafe=*/false );
4878 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4880 SMESH_CATCH( SMESH::throwCorbaException );
4884 //=======================================================================
4887 //=======================================================================
4889 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4890 const SMESH::PointStruct& thePoint,
4891 const SMESH::double_array& theScaleFact,
4892 CORBA::Boolean theCopy)
4893 throw (SALOME::SALOME_Exception)
4895 if ( !myIsPreviewMode ) {
4896 TPythonDump() << this << ".Scale( "
4897 << theObject << ", "
4899 << TVar( theScaleFact ) << ", "
4902 scale(theObject, thePoint, theScaleFact, theCopy, false);
4906 //=======================================================================
4907 //function : ScaleMakeGroups
4909 //=======================================================================
4911 SMESH::ListOfGroups*
4912 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4913 const SMESH::PointStruct& thePoint,
4914 const SMESH::double_array& theScaleFact)
4915 throw (SALOME::SALOME_Exception)
4917 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4919 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4920 if (!myIsPreviewMode) {
4921 dumpGroupsList(aPythonDump, aGroups);
4922 aPythonDump << this << ".Scale("
4925 << TVar( theScaleFact ) << ",True,True)";
4931 //=======================================================================
4932 //function : ScaleMakeMesh
4934 //=======================================================================
4936 SMESH::SMESH_Mesh_ptr
4937 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4938 const SMESH::PointStruct& thePoint,
4939 const SMESH::double_array& theScaleFact,
4940 CORBA::Boolean theCopyGroups,
4941 const char* theMeshName)
4942 throw (SALOME::SALOME_Exception)
4944 SMESH_Mesh_i* mesh_i;
4945 SMESH::SMESH_Mesh_var mesh;
4946 { // open new scope to dump "MakeMesh" command
4947 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4949 TPythonDump pydump; // to prevent dump at mesh creation
4950 mesh = makeMesh( theMeshName );
4951 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4955 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4956 mesh_i->CreateGroupServants();
4958 if ( !myIsPreviewMode )
4959 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4960 << theObject << ", "
4962 << TVar( theScaleFact ) << ", "
4963 << theCopyGroups << ", '"
4964 << theMeshName << "' )";
4968 if (!myIsPreviewMode && mesh_i)
4969 mesh_i->GetGroups();
4971 return mesh._retn();
4975 //=======================================================================
4976 //function : FindCoincidentNodes
4978 //=======================================================================
4980 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4981 SMESH::array_of_long_array_out GroupsOfNodes)
4982 throw (SALOME::SALOME_Exception)
4987 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4988 TIDSortedNodeSet nodes; // no input nodes
4989 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4991 GroupsOfNodes = new SMESH::array_of_long_array;
4992 GroupsOfNodes->length( aListOfListOfNodes.size() );
4993 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4994 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4995 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4996 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4997 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4998 aGroup.length( aListOfNodes.size() );
4999 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
5000 aGroup[ j ] = (*lIt)->GetID();
5002 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
5003 << Tolerance << " )";
5005 SMESH_CATCH( SMESH::throwCorbaException );
5008 //=======================================================================
5009 //function : FindCoincidentNodesOnPart
5011 //=======================================================================
5013 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
5014 CORBA::Double Tolerance,
5015 SMESH::array_of_long_array_out GroupsOfNodes)
5016 throw (SALOME::SALOME_Exception)
5021 TIDSortedNodeSet nodes;
5022 prepareIdSource( theObject );
5023 idSourceToNodeSet( theObject, getMeshDS(), nodes );
5025 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
5027 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
5029 GroupsOfNodes = new SMESH::array_of_long_array;
5030 GroupsOfNodes->length( aListOfListOfNodes.size() );
5031 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
5032 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
5034 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
5035 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
5036 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
5037 aGroup.length( aListOfNodes.size() );
5038 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
5039 aGroup[ j ] = (*lIt)->GetID();
5041 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
5043 << Tolerance << " )";
5045 SMESH_CATCH( SMESH::throwCorbaException );
5048 //================================================================================
5050 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
5051 * ExceptSubMeshOrGroups
5053 //================================================================================
5055 void SMESH_MeshEditor_i::
5056 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
5057 CORBA::Double theTolerance,
5058 SMESH::array_of_long_array_out theGroupsOfNodes,
5059 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
5060 throw (SALOME::SALOME_Exception)
5065 TIDSortedNodeSet nodes;
5066 prepareIdSource( theObject );
5067 idSourceToNodeSet( theObject, getMeshDS(), nodes );
5069 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
5071 TIDSortedNodeSet exceptNodes;
5072 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
5073 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
5074 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
5075 nodes.erase( *avoidNode );
5077 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
5079 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
5081 theGroupsOfNodes = new SMESH::array_of_long_array;
5082 theGroupsOfNodes->length( aListOfListOfNodes.size() );
5083 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
5084 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
5086 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
5087 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
5088 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
5089 aGroup.length( aListOfNodes.size() );
5090 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
5091 aGroup[ j ] = (*lIt)->GetID();
5093 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
5095 << theTolerance << ", "
5096 << theExceptSubMeshOrGroups << " )";
5098 SMESH_CATCH( SMESH::throwCorbaException );
5101 //=======================================================================
5102 //function : MergeNodes
5104 //=======================================================================
5106 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
5107 throw (SALOME::SALOME_Exception)
5112 SMESHDS_Mesh* aMesh = getMeshDS();
5114 TPythonDump aTPythonDump;
5115 aTPythonDump << this << ".MergeNodes([";
5116 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
5117 for (int i = 0; i < GroupsOfNodes.length(); i++)
5119 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
5120 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
5121 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
5122 for ( int j = 0; j < aNodeGroup.length(); j++ )
5124 CORBA::Long index = aNodeGroup[ j ];
5125 const SMDS_MeshNode * node = aMesh->FindNode(index);
5127 aListOfNodes.push_back( node );
5129 if ( aListOfNodes.size() < 2 )
5130 aListOfListOfNodes.pop_back();
5132 if ( i > 0 ) aTPythonDump << ", ";
5133 aTPythonDump << aNodeGroup;
5135 getEditor().MergeNodes( aListOfListOfNodes );
5137 aTPythonDump << "])";
5139 declareMeshModified( /*isReComputeSafe=*/false );
5141 SMESH_CATCH( SMESH::throwCorbaException );
5144 //=======================================================================
5145 //function : FindEqualElements
5147 //=======================================================================
5149 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
5150 SMESH::array_of_long_array_out GroupsOfElementsID)
5151 throw (SALOME::SALOME_Exception)
5156 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
5157 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
5159 TIDSortedElemSet elems;
5160 prepareIdSource( theObject );
5161 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
5163 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
5164 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
5166 GroupsOfElementsID = new SMESH::array_of_long_array;
5167 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
5169 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
5170 aListOfListOfElementsID.begin();
5171 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
5173 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
5174 list<int>& listOfIDs = *arraysIt;
5175 aGroup.length( listOfIDs.size() );
5176 list<int>::iterator idIt = listOfIDs.begin();
5177 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
5178 aGroup[ k ] = *idIt;
5181 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
5185 SMESH_CATCH( SMESH::throwCorbaException );
5188 //=======================================================================
5189 //function : MergeElements
5191 //=======================================================================
5193 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
5194 throw (SALOME::SALOME_Exception)
5199 TPythonDump aTPythonDump;
5200 aTPythonDump << this << ".MergeElements( [";
5202 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
5204 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
5205 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
5206 aListOfListOfElementsID.push_back( list< int >() );
5207 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
5208 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
5209 CORBA::Long id = anElemsIDGroup[ j ];
5210 aListOfElemsID.push_back( id );
5212 if ( aListOfElemsID.size() < 2 )
5213 aListOfListOfElementsID.pop_back();
5214 if ( i > 0 ) aTPythonDump << ", ";
5215 aTPythonDump << anElemsIDGroup;
5218 getEditor().MergeElements(aListOfListOfElementsID);
5220 declareMeshModified( /*isReComputeSafe=*/true );
5222 aTPythonDump << "] )";
5224 SMESH_CATCH( SMESH::throwCorbaException );
5227 //=======================================================================
5228 //function : MergeEqualElements
5230 //=======================================================================
5232 void SMESH_MeshEditor_i::MergeEqualElements()
5233 throw (SALOME::SALOME_Exception)
5238 getEditor().MergeEqualElements();
5240 declareMeshModified( /*isReComputeSafe=*/true );
5242 TPythonDump() << this << ".MergeEqualElements()";
5244 SMESH_CATCH( SMESH::throwCorbaException );
5247 //=============================================================================
5249 * Move the node to a given point
5251 //=============================================================================
5253 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
5257 throw (SALOME::SALOME_Exception)
5260 initData(/*deleteSearchers=*/false);
5262 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
5266 if ( theNodeSearcher )
5267 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5269 if ( myIsPreviewMode ) // make preview data
5271 // in a preview mesh, make edges linked to a node
5272 TPreviewMesh& tmpMesh = *getPreviewMesh();
5273 TIDSortedElemSet linkedNodes;
5274 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5275 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5276 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
5277 for ( ; nIt != linkedNodes.end(); ++nIt )
5279 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
5280 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
5284 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
5285 // fill preview data
5287 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5288 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5290 getMeshDS()->MoveNode(node, x, y, z);
5292 if ( !myIsPreviewMode )
5294 // Update Python script
5295 TPythonDump() << "isDone = " << this << ".MoveNode( "
5296 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
5297 declareMeshModified( /*isReComputeSafe=*/false );
5300 SMESH_CATCH( SMESH::throwCorbaException );
5305 //================================================================================
5307 * \brief Return ID of node closest to a given point
5309 //================================================================================
5311 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
5314 throw (SALOME::SALOME_Exception)
5317 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5319 if ( !theNodeSearcher ) {
5320 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5323 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
5324 return node->GetID();
5326 SMESH_CATCH( SMESH::throwCorbaException );
5330 //================================================================================
5332 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
5333 * move the node closest to the point to point's location and return ID of the node
5335 //================================================================================
5337 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
5340 CORBA::Long theNodeID)
5341 throw (SALOME::SALOME_Exception)
5344 // We keep theNodeSearcher until any mesh modification:
5345 // 1) initData() deletes theNodeSearcher at any edition,
5346 // 2) TSearchersDeleter - at any mesh compute event and mesh change
5348 initData(/*deleteSearchers=*/false);
5350 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5352 int nodeID = theNodeID;
5353 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
5354 if ( !node ) // preview moving node
5356 if ( !theNodeSearcher ) {
5357 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5360 node = theNodeSearcher->FindClosestTo( p );
5363 nodeID = node->GetID();
5364 if ( myIsPreviewMode ) // make preview data
5366 // in a preview mesh, make edges linked to a node
5367 TPreviewMesh tmpMesh = *getPreviewMesh();
5368 TIDSortedElemSet linkedNodes;
5369 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5370 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5371 for ( ; nIt != linkedNodes.end(); ++nIt )
5373 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
5374 tmpMesh.Copy( &edge );
5377 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
5379 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
5380 // fill preview data
5382 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5384 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5388 getMeshDS()->MoveNode(node, x, y, z);
5392 if ( !myIsPreviewMode )
5394 TPythonDump() << "nodeID = " << this
5395 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
5396 << ", " << nodeID << " )";
5398 declareMeshModified( /*isReComputeSafe=*/false );
5403 SMESH_CATCH( SMESH::throwCorbaException );
5407 //=======================================================================
5409 * Return elements of given type where the given point is IN or ON.
5411 * 'ALL' type means elements of any type excluding nodes
5413 //=======================================================================
5415 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
5418 SMESH::ElementType type)
5419 throw (SALOME::SALOME_Exception)
5422 SMESH::long_array_var res = new SMESH::long_array;
5423 vector< const SMDS_MeshElement* > foundElems;
5425 theSearchersDeleter.Set( myMesh );
5426 if ( !theElementSearcher ) {
5427 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5429 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5430 SMDSAbs_ElementType( type ),
5432 res->length( foundElems.size() );
5433 for ( int i = 0; i < foundElems.size(); ++i )
5434 res[i] = foundElems[i]->GetID();
5438 SMESH_CATCH( SMESH::throwCorbaException );
5442 //=======================================================================
5443 //function : FindAmongElementsByPoint
5444 //purpose : Searching among the given elements, return elements of given type
5445 // where the given point is IN or ON.
5446 // 'ALL' type means elements of any type excluding nodes
5447 //=======================================================================
5450 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
5454 SMESH::ElementType type)
5455 throw (SALOME::SALOME_Exception)
5458 SMESH::long_array_var res = new SMESH::long_array;
5460 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
5461 if ( types->length() == 1 && // a part contains only nodes or 0D elements
5462 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
5463 type != types[0] ) // but search of elements of dim > 0
5466 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
5467 return FindElementsByPoint( x,y,z, type );
5469 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
5471 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
5472 if ( !theElementSearcher )
5474 // create a searcher from elementIDs
5475 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
5476 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
5478 if ( !idSourceToSet( elementIDs, meshDS, elements,
5479 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
5482 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5483 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
5485 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
5488 vector< const SMDS_MeshElement* > foundElems;
5490 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5491 SMDSAbs_ElementType( type ),
5493 res->length( foundElems.size() );
5494 for ( int i = 0; i < foundElems.size(); ++i )
5495 res[i] = foundElems[i]->GetID();
5499 SMESH_CATCH( SMESH::throwCorbaException );
5503 //=======================================================================
5504 //function : GetPointState
5505 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
5506 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
5507 //=======================================================================
5509 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
5512 throw (SALOME::SALOME_Exception)
5515 theSearchersDeleter.Set( myMesh );
5516 if ( !theElementSearcher ) {
5517 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5519 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
5521 SMESH_CATCH( SMESH::throwCorbaException );
5525 //=======================================================================
5526 //function : convError
5528 //=======================================================================
5530 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
5532 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
5536 RETCASE( SEW_BORDER1_NOT_FOUND );
5537 RETCASE( SEW_BORDER2_NOT_FOUND );
5538 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
5539 RETCASE( SEW_BAD_SIDE_NODES );
5540 RETCASE( SEW_VOLUMES_TO_SPLIT );
5541 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
5542 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
5543 RETCASE( SEW_BAD_SIDE1_NODES );
5544 RETCASE( SEW_BAD_SIDE2_NODES );
5546 return SMESH::SMESH_MeshEditor::SEW_OK;
5549 //=======================================================================
5550 //function : SewFreeBorders
5552 //=======================================================================
5554 SMESH::SMESH_MeshEditor::Sew_Error
5555 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
5556 CORBA::Long SecondNodeID1,
5557 CORBA::Long LastNodeID1,
5558 CORBA::Long FirstNodeID2,
5559 CORBA::Long SecondNodeID2,
5560 CORBA::Long LastNodeID2,
5561 CORBA::Boolean CreatePolygons,
5562 CORBA::Boolean CreatePolyedrs)
5563 throw (SALOME::SALOME_Exception)
5568 SMESHDS_Mesh* aMesh = getMeshDS();
5570 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5571 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5572 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5573 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5574 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5575 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
5577 if (!aBorderFirstNode ||
5578 !aBorderSecondNode||
5580 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5581 if (!aSide2FirstNode ||
5582 !aSide2SecondNode ||
5584 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5586 TPythonDump() << "error = " << this << ".SewFreeBorders( "
5587 << FirstNodeID1 << ", "
5588 << SecondNodeID1 << ", "
5589 << LastNodeID1 << ", "
5590 << FirstNodeID2 << ", "
5591 << SecondNodeID2 << ", "
5592 << LastNodeID2 << ", "
5593 << CreatePolygons<< ", "
5594 << CreatePolyedrs<< " )";
5596 SMESH::SMESH_MeshEditor::Sew_Error error =
5597 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5608 declareMeshModified( /*isReComputeSafe=*/false );
5611 SMESH_CATCH( SMESH::throwCorbaException );
5612 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5616 //=======================================================================
5617 //function : SewConformFreeBorders
5619 //=======================================================================
5621 SMESH::SMESH_MeshEditor::Sew_Error
5622 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
5623 CORBA::Long SecondNodeID1,
5624 CORBA::Long LastNodeID1,
5625 CORBA::Long FirstNodeID2,
5626 CORBA::Long SecondNodeID2)
5627 throw (SALOME::SALOME_Exception)
5632 SMESHDS_Mesh* aMesh = getMeshDS();
5634 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5635 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5636 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5637 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5638 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5639 const SMDS_MeshNode* aSide2ThirdNode = 0;
5641 if (!aBorderFirstNode ||
5642 !aBorderSecondNode||
5644 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5645 if (!aSide2FirstNode ||
5647 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5649 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
5650 << FirstNodeID1 << ", "
5651 << SecondNodeID1 << ", "
5652 << LastNodeID1 << ", "
5653 << FirstNodeID2 << ", "
5654 << SecondNodeID2 << " )";
5656 SMESH::SMESH_MeshEditor::Sew_Error error =
5657 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5666 declareMeshModified( /*isReComputeSafe=*/false );
5669 SMESH_CATCH( SMESH::throwCorbaException );
5670 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5674 //=======================================================================
5675 //function : SewBorderToSide
5677 //=======================================================================
5679 SMESH::SMESH_MeshEditor::Sew_Error
5680 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5681 CORBA::Long SecondNodeIDOnFreeBorder,
5682 CORBA::Long LastNodeIDOnFreeBorder,
5683 CORBA::Long FirstNodeIDOnSide,
5684 CORBA::Long LastNodeIDOnSide,
5685 CORBA::Boolean CreatePolygons,
5686 CORBA::Boolean CreatePolyedrs)
5687 throw (SALOME::SALOME_Exception)
5692 SMESHDS_Mesh* aMesh = getMeshDS();
5694 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5695 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5696 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5697 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5698 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5699 const SMDS_MeshNode* aSide2ThirdNode = 0;
5701 if (!aBorderFirstNode ||
5702 !aBorderSecondNode||
5704 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5705 if (!aSide2FirstNode ||
5707 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5709 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5710 << FirstNodeIDOnFreeBorder << ", "
5711 << SecondNodeIDOnFreeBorder << ", "
5712 << LastNodeIDOnFreeBorder << ", "
5713 << FirstNodeIDOnSide << ", "
5714 << LastNodeIDOnSide << ", "
5715 << CreatePolygons << ", "
5716 << CreatePolyedrs << ") ";
5718 SMESH::SMESH_MeshEditor::Sew_Error error =
5719 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5729 declareMeshModified( /*isReComputeSafe=*/false );
5732 SMESH_CATCH( SMESH::throwCorbaException );
5733 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5737 //=======================================================================
5738 //function : SewSideElements
5740 //=======================================================================
5742 SMESH::SMESH_MeshEditor::Sew_Error
5743 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5744 const SMESH::long_array& IDsOfSide2Elements,
5745 CORBA::Long NodeID1OfSide1ToMerge,
5746 CORBA::Long NodeID1OfSide2ToMerge,
5747 CORBA::Long NodeID2OfSide1ToMerge,
5748 CORBA::Long NodeID2OfSide2ToMerge)
5749 throw (SALOME::SALOME_Exception)
5754 SMESHDS_Mesh* aMesh = getMeshDS();
5756 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5757 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5758 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5759 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5761 if (!aFirstNode1ToMerge ||
5762 !aFirstNode2ToMerge )
5763 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5764 if (!aSecondNode1ToMerge||
5765 !aSecondNode2ToMerge)
5766 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5768 TIDSortedElemSet aSide1Elems, aSide2Elems;
5769 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5770 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5772 TPythonDump() << "error = " << this << ".SewSideElements( "
5773 << IDsOfSide1Elements << ", "
5774 << IDsOfSide2Elements << ", "
5775 << NodeID1OfSide1ToMerge << ", "
5776 << NodeID1OfSide2ToMerge << ", "
5777 << NodeID2OfSide1ToMerge << ", "
5778 << NodeID2OfSide2ToMerge << ")";
5780 SMESH::SMESH_MeshEditor::Sew_Error error =
5781 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5784 aSecondNode1ToMerge,
5785 aSecondNode2ToMerge));
5787 declareMeshModified( /*isReComputeSafe=*/false );
5790 SMESH_CATCH( SMESH::throwCorbaException );
5791 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5794 //================================================================================
5796 * \brief Set new nodes for given element
5797 * \param ide - element id
5798 * \param newIDs - new node ids
5799 * \retval CORBA::Boolean - true if result is OK
5801 //================================================================================
5803 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5804 const SMESH::long_array& newIDs)
5805 throw (SALOME::SALOME_Exception)
5810 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5811 if(!elem) return false;
5813 int nbn = newIDs.length();
5815 vector<const SMDS_MeshNode*> aNodes(nbn);
5818 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5821 aNodes[nbn1] = aNode;
5824 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5825 << ide << ", " << newIDs << " )";
5827 MESSAGE("ChangeElementNodes");
5828 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5830 declareMeshModified( /*isReComputeSafe=*/ !res );
5834 SMESH_CATCH( SMESH::throwCorbaException );
5838 //=======================================================================
5840 * \brief Makes a part of the mesh quadratic or bi-quadratic
5842 //=======================================================================
5844 void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d,
5845 CORBA::Boolean theToBiQuad,
5846 SMESH::SMESH_IDSource_ptr theObject)
5847 throw (SALOME::SALOME_Exception)
5850 TIDSortedElemSet elems;
5852 if ( !( elemsOK = CORBA::is_nil( theObject )))
5854 prepareIdSource( theObject );
5855 elemsOK = idSourceToSet( theObject, getMeshDS(), elems,
5856 SMDSAbs_All, /*emptyIfIsMesh=*/true );
5860 if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
5861 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5863 if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
5864 else getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
5866 declareMeshModified( /*isReComputeSafe=*/false );
5869 SMESH_CATCH( SMESH::throwCorbaException );
5872 //=======================================================================
5873 //function : ConvertFromQuadratic
5875 //=======================================================================
5877 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5878 throw (SALOME::SALOME_Exception)
5880 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5881 TPythonDump() << this << ".ConvertFromQuadratic()";
5882 declareMeshModified( /*isReComputeSafe=*/!isDone );
5886 //=======================================================================
5887 //function : ConvertToQuadratic
5889 //=======================================================================
5891 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5892 throw (SALOME::SALOME_Exception)
5894 convertToQuadratic( theForce3d, false );
5895 TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
5898 //================================================================================
5900 * \brief Makes a part of the mesh quadratic
5902 //================================================================================
5904 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5905 SMESH::SMESH_IDSource_ptr theObject)
5906 throw (SALOME::SALOME_Exception)
5908 convertToQuadratic( theForce3d, false, theObject );
5909 TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
5912 //================================================================================
5914 * \brief Makes a part of the mesh bi-quadratic
5916 //================================================================================
5918 void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean theForce3d,
5919 SMESH::SMESH_IDSource_ptr theObject)
5920 throw (SALOME::SALOME_Exception)
5922 convertToQuadratic( theForce3d, true, theObject );
5923 TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
5926 //================================================================================
5928 * \brief Makes a part of the mesh linear
5930 //================================================================================
5932 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5933 throw (SALOME::SALOME_Exception)
5939 TIDSortedElemSet elems;
5940 prepareIdSource( theObject );
5941 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5943 if ( elems.empty() )
5945 ConvertFromQuadratic();
5947 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5949 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5953 getEditor().ConvertFromQuadratic(elems);
5956 declareMeshModified( /*isReComputeSafe=*/false );
5958 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5960 SMESH_CATCH( SMESH::throwCorbaException );
5963 //=======================================================================
5964 //function : makeMesh
5965 //purpose : create a named imported mesh
5966 //=======================================================================
5968 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5970 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5971 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5972 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5973 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5974 gen->SetName( meshSO, theMeshName, "Mesh" );
5975 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5977 return mesh._retn();
5980 //=======================================================================
5981 //function : dumpGroupsList
5983 //=======================================================================
5985 void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPython,
5986 const SMESH::ListOfGroups * theGroupList)
5988 bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
5989 if ( isDumpGroupList )
5990 theDumpPython << theGroupList << " = ";
5993 //================================================================================
5995 \brief Generates the unique group name.
5996 \param thePrefix name prefix
5999 //================================================================================
6001 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
6003 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
6004 set<string> groupNames;
6006 // Get existing group names
6007 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
6008 SMESH::SMESH_GroupBase_var aGroup = groups[i];
6009 if (CORBA::is_nil(aGroup))
6012 CORBA::String_var name = aGroup->GetName();
6013 groupNames.insert( name.in() );
6017 string name = thePrefix;
6020 while (!groupNames.insert(name).second)
6021 name = SMESH_Comment( thePrefix ) << "_" << index++;
6026 //================================================================================
6028 * \brief Prepare SMESH_IDSource for work
6030 //================================================================================
6032 void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
6034 if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6036 SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
6037 filter->SetMesh( mesh );
6041 //================================================================================
6043 * \brief Duplicates given elements, i.e. creates new elements based on the
6044 * same nodes as the given ones.
6045 * \param theElements - container of elements to duplicate.
6046 * \param theGroupName - a name of group to contain the generated elements.
6047 * If a group with such a name already exists, the new elements
6048 * are added to the existng group, else a new group is created.
6049 * If \a theGroupName is empty, new elements are not added
6051 * \return a group where the new elements are added. NULL if theGroupName == "".
6054 //================================================================================
6056 SMESH::SMESH_Group_ptr
6057 SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
6058 const char* theGroupName)
6059 throw (SALOME::SALOME_Exception)
6061 SMESH::SMESH_Group_var newGroup;
6068 TIDSortedElemSet elems;
6069 prepareIdSource( theElements );
6070 if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
6072 getEditor().DoubleElements( elems );
6074 if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
6077 SMESH::ElementType type =
6078 SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
6079 // find existing group
6080 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
6081 for ( size_t i = 0; i < groups->length(); ++i )
6082 if ( groups[i]->GetType() == type )
6084 CORBA::String_var name = groups[i]->GetName();
6085 if ( strcmp( name, theGroupName ) == 0 ) {
6086 newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
6090 // create a new group
6091 if ( newGroup->_is_nil() )
6092 newGroup = myMesh_i->CreateGroup( type, theGroupName );
6094 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
6096 SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
6097 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
6098 for ( int i = 1; i <= aSeq.Length(); i++ )
6099 groupDS->SMDSGroup().Add( aSeq(i) );
6104 if ( !newGroup->_is_nil() )
6105 pyDump << newGroup << " = ";
6106 pyDump << this << ".DoubleElements( "
6107 << theElements << ", " << "'" << theGroupName <<"')";
6109 SMESH_CATCH( SMESH::throwCorbaException );
6111 return newGroup._retn();
6114 //================================================================================
6116 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6117 \param theNodes - identifiers of nodes to be doubled
6118 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
6119 nodes. If list of element identifiers is empty then nodes are doubled but
6120 they not assigned to elements
6121 \return TRUE if operation has been completed successfully, FALSE otherwise
6122 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
6124 //================================================================================
6126 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
6127 const SMESH::long_array& theModifiedElems )
6128 throw (SALOME::SALOME_Exception)
6133 list< int > aListOfNodes;
6135 for ( i = 0, n = theNodes.length(); i < n; i++ )
6136 aListOfNodes.push_back( theNodes[ i ] );
6138 list< int > aListOfElems;
6139 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
6140 aListOfElems.push_back( theModifiedElems[ i ] );
6142 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
6144 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6146 // Update Python script
6147 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
6151 SMESH_CATCH( SMESH::throwCorbaException );
6155 //================================================================================
6157 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6158 This method provided for convenience works as DoubleNodes() described above.
6159 \param theNodeId - identifier of node to be doubled.
6160 \param theModifiedElems - identifiers of elements to be updated.
6161 \return TRUE if operation has been completed successfully, FALSE otherwise
6162 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
6164 //================================================================================
6166 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
6167 const SMESH::long_array& theModifiedElems )
6168 throw (SALOME::SALOME_Exception)
6171 SMESH::long_array_var aNodes = new SMESH::long_array;
6172 aNodes->length( 1 );
6173 aNodes[ 0 ] = theNodeId;
6175 TPythonDump pyDump; // suppress dump by the next line
6177 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
6179 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
6183 SMESH_CATCH( SMESH::throwCorbaException );
6187 //================================================================================
6189 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6190 This method provided for convenience works as DoubleNodes() described above.
6191 \param theNodes - group of nodes to be doubled.
6192 \param theModifiedElems - group of elements to be updated.
6193 \return TRUE if operation has been completed successfully, FALSE otherwise
6194 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
6196 //================================================================================
6198 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
6199 SMESH::SMESH_GroupBase_ptr theModifiedElems )
6200 throw (SALOME::SALOME_Exception)
6203 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
6206 SMESH::long_array_var aNodes = theNodes->GetListOfID();
6207 SMESH::long_array_var aModifiedElems;
6208 if ( !CORBA::is_nil( theModifiedElems ) )
6209 aModifiedElems = theModifiedElems->GetListOfID();
6212 aModifiedElems = new SMESH::long_array;
6213 aModifiedElems->length( 0 );
6216 TPythonDump pyDump; // suppress dump by the next line
6218 bool done = DoubleNodes( aNodes, aModifiedElems );
6220 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
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 DoubleNodeGroup(), but returns a new group with newly created nodes.
6232 * \param theNodes - group of nodes to be doubled.
6233 * \param theModifiedElems - group of elements to be updated.
6234 * \return a new group with newly created nodes
6235 * \sa DoubleNodeGroup()
6237 //================================================================================
6239 SMESH::SMESH_Group_ptr
6240 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
6241 SMESH::SMESH_GroupBase_ptr theModifiedElems )
6242 throw (SALOME::SALOME_Exception)
6245 SMESH::SMESH_Group_var aNewGroup;
6247 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
6248 return aNewGroup._retn();
6251 SMESH::long_array_var aNodes = theNodes->GetListOfID();
6252 SMESH::long_array_var aModifiedElems;
6253 if ( !CORBA::is_nil( theModifiedElems ) )
6254 aModifiedElems = theModifiedElems->GetListOfID();
6256 aModifiedElems = new SMESH::long_array;
6257 aModifiedElems->length( 0 );
6260 TPythonDump pyDump; // suppress dump by the next line
6262 bool aResult = DoubleNodes( aNodes, aModifiedElems );
6265 // Create group with newly created nodes
6266 SMESH::long_array_var anIds = GetLastCreatedNodes();
6267 if (anIds->length() > 0) {
6268 string anUnindexedName (theNodes->GetName());
6269 string aNewName = generateGroupName(anUnindexedName + "_double");
6270 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6271 aNewGroup->Add(anIds);
6272 pyDump << aNewGroup << " = ";
6276 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
6277 << theModifiedElems << " )";
6279 return aNewGroup._retn();
6281 SMESH_CATCH( SMESH::throwCorbaException );
6285 //================================================================================
6287 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6288 This method provided for convenience works as DoubleNodes() described above.
6289 \param theNodes - list of groups of nodes to be doubled
6290 \param theModifiedElems - list of groups of elements to be updated.
6291 \return TRUE if operation has been completed successfully, FALSE otherwise
6292 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
6294 //================================================================================
6296 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
6297 const SMESH::ListOfGroups& theModifiedElems )
6298 throw (SALOME::SALOME_Exception)
6303 std::list< int > aNodes;
6305 for ( i = 0, n = theNodes.length(); i < n; i++ )
6307 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
6308 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
6310 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6311 for ( j = 0, m = aCurr->length(); j < m; j++ )
6312 aNodes.push_back( aCurr[ j ] );
6316 std::list< int > anElems;
6317 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
6319 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
6320 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
6322 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6323 for ( j = 0, m = aCurr->length(); j < m; j++ )
6324 anElems.push_back( aCurr[ j ] );
6328 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
6330 declareMeshModified( /*isReComputeSafe=*/false );
6332 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
6336 SMESH_CATCH( SMESH::throwCorbaException );
6340 //================================================================================
6342 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6343 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
6344 * \param theNodes - group of nodes to be doubled.
6345 * \param theModifiedElems - group of elements to be updated.
6346 * \return a new group with newly created nodes
6347 * \sa DoubleNodeGroups()
6349 //================================================================================
6351 SMESH::SMESH_Group_ptr
6352 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
6353 const SMESH::ListOfGroups& theModifiedElems )
6354 throw (SALOME::SALOME_Exception)
6356 SMESH::SMESH_Group_var aNewGroup;
6358 TPythonDump pyDump; // suppress dump by the next line
6360 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
6364 // Create group with newly created nodes
6365 SMESH::long_array_var anIds = GetLastCreatedNodes();
6366 if (anIds->length() > 0) {
6367 string anUnindexedName (theNodes[0]->GetName());
6368 string aNewName = generateGroupName(anUnindexedName + "_double");
6369 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6370 aNewGroup->Add(anIds);
6371 pyDump << aNewGroup << " = ";
6375 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
6376 << theModifiedElems << " )";
6378 return aNewGroup._retn();
6382 //================================================================================
6384 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6385 \param theElems - the list of elements (edges or faces) to be replicated
6386 The nodes for duplication could be found from these elements
6387 \param theNodesNot - list of nodes to NOT replicate
6388 \param theAffectedElems - the list of elements (cells and edges) to which the
6389 replicated nodes should be associated to.
6390 \return TRUE if operation has been completed successfully, FALSE otherwise
6391 \sa DoubleNodeGroup(), DoubleNodeGroups()
6393 //================================================================================
6395 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
6396 const SMESH::long_array& theNodesNot,
6397 const SMESH::long_array& theAffectedElems )
6398 throw (SALOME::SALOME_Exception)
6403 SMESHDS_Mesh* aMeshDS = getMeshDS();
6404 TIDSortedElemSet anElems, aNodes, anAffected;
6405 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6406 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6407 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
6409 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6411 // Update Python script
6412 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
6413 << theNodesNot << ", " << theAffectedElems << " )";
6415 declareMeshModified( /*isReComputeSafe=*/false );
6418 SMESH_CATCH( SMESH::throwCorbaException );
6422 //================================================================================
6424 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6425 \param theElems - the list of elements (edges or faces) to be replicated
6426 The nodes for duplication could be found from these elements
6427 \param theNodesNot - list of nodes to NOT replicate
6428 \param theShape - shape to detect affected elements (element which geometric center
6429 located on or inside shape).
6430 The replicated nodes should be associated to affected elements.
6431 \return TRUE if operation has been completed successfully, FALSE otherwise
6432 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
6434 //================================================================================
6436 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
6437 const SMESH::long_array& theNodesNot,
6438 GEOM::GEOM_Object_ptr theShape )
6439 throw (SALOME::SALOME_Exception)
6445 SMESHDS_Mesh* aMeshDS = getMeshDS();
6446 TIDSortedElemSet anElems, aNodes;
6447 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6448 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6450 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6451 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6453 // Update Python script
6454 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
6455 << theNodesNot << ", " << theShape << " )";
6457 declareMeshModified( /*isReComputeSafe=*/false );
6460 SMESH_CATCH( SMESH::throwCorbaException );
6464 //================================================================================
6466 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6467 \param theElems - group of of elements (edges or faces) to be replicated
6468 \param theNodesNot - group of nodes not to replicated
6469 \param theAffectedElems - group of elements to which the replicated nodes
6470 should be associated to.
6471 \return TRUE if operation has been completed successfully, FALSE otherwise
6472 \sa DoubleNodes(), DoubleNodeGroups()
6474 //================================================================================
6477 SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
6478 SMESH::SMESH_GroupBase_ptr theNodesNot,
6479 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6480 throw (SALOME::SALOME_Exception)
6483 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6489 SMESHDS_Mesh* aMeshDS = getMeshDS();
6490 TIDSortedElemSet anElems, aNodes, anAffected;
6491 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6492 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6493 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6495 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6497 // Update Python script
6498 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
6499 << theNodesNot << ", " << theAffectedElems << " )";
6501 declareMeshModified( /*isReComputeSafe=*/false );
6504 SMESH_CATCH( SMESH::throwCorbaException );
6508 //================================================================================
6510 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6511 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6512 * \param theElems - group of of elements (edges or faces) to be replicated
6513 * \param theNodesNot - group of nodes not to replicated
6514 * \param theAffectedElems - group of elements to which the replicated nodes
6515 * should be associated to.
6516 * \return a new group with newly created elements
6517 * \sa DoubleNodeElemGroup()
6519 //================================================================================
6521 SMESH::SMESH_Group_ptr
6522 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
6523 SMESH::SMESH_GroupBase_ptr theNodesNot,
6524 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6525 throw (SALOME::SALOME_Exception)
6528 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
6532 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6533 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6535 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
6537 << theNodesNot << ", "
6538 << theAffectedElems << " )";
6540 return elemGroup._retn();
6543 //================================================================================
6545 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6546 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6547 * \param theElems - group of of elements (edges or faces) to be replicated
6548 * \param theNodesNot - group of nodes not to replicated
6549 * \param theAffectedElems - group of elements to which the replicated nodes
6550 * should be associated to.
6551 * \return a new group with newly created elements
6552 * \sa DoubleNodeElemGroup()
6554 //================================================================================
6556 SMESH::ListOfGroups*
6557 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
6558 SMESH::SMESH_GroupBase_ptr theNodesNot,
6559 SMESH::SMESH_GroupBase_ptr theAffectedElems,
6560 CORBA::Boolean theElemGroupNeeded,
6561 CORBA::Boolean theNodeGroupNeeded)
6562 throw (SALOME::SALOME_Exception)
6565 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6566 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6567 aTwoGroups->length( 2 );
6569 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6570 return aTwoGroups._retn();
6575 SMESHDS_Mesh* aMeshDS = getMeshDS();
6576 TIDSortedElemSet anElems, aNodes, anAffected;
6577 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6578 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6579 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6582 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6584 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6590 // Create group with newly created elements
6591 CORBA::String_var elemGroupName = theElems->GetName();
6592 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6593 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6595 SMESH::long_array_var anIds = GetLastCreatedElems();
6596 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6597 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6598 aNewElemGroup->Add(anIds);
6600 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6602 SMESH::long_array_var anIds = GetLastCreatedNodes();
6603 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6604 aNewNodeGroup->Add(anIds);
6608 // Update Python script
6611 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6612 else pyDump << aNewElemGroup << ", ";
6613 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6614 else pyDump << aNewNodeGroup << " ] = ";
6616 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
6617 << theNodesNot << ", "
6618 << theAffectedElems << ", "
6619 << theElemGroupNeeded << ", "
6620 << theNodeGroupNeeded <<" )";
6622 aTwoGroups[0] = aNewElemGroup._retn();
6623 aTwoGroups[1] = aNewNodeGroup._retn();
6624 return aTwoGroups._retn();
6626 SMESH_CATCH( SMESH::throwCorbaException );
6630 //================================================================================
6632 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6633 \param theElems - group of of elements (edges or faces) to be replicated
6634 \param theNodesNot - group of nodes not to replicated
6635 \param theShape - shape to detect affected elements (element which geometric center
6636 located on or inside shape).
6637 The replicated nodes should be associated to affected elements.
6638 \return TRUE if operation has been completed successfully, FALSE otherwise
6639 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
6641 //================================================================================
6644 SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
6645 SMESH::SMESH_GroupBase_ptr theNodesNot,
6646 GEOM::GEOM_Object_ptr theShape )
6647 throw (SALOME::SALOME_Exception)
6650 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6656 SMESHDS_Mesh* aMeshDS = getMeshDS();
6657 TIDSortedElemSet anElems, aNodes, anAffected;
6658 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6659 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6661 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6662 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6665 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6667 // Update Python script
6668 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
6669 << theNodesNot << ", " << theShape << " )";
6672 SMESH_CATCH( SMESH::throwCorbaException );
6676 //================================================================================
6678 * \brief Re-load elements from a list of groups into a TIDSortedElemSet
6679 * \param [in] theGrpList - groups
6680 * \param [in] theMeshDS - mesh
6681 * \param [out] theElemSet - set of elements
6682 * \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
6684 //================================================================================
6686 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
6687 SMESHDS_Mesh* theMeshDS,
6688 TIDSortedElemSet& theElemSet,
6689 const bool theIsNodeGrp)
6691 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
6693 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
6694 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
6695 : aGrp->GetType() != SMESH::NODE ) )
6697 SMESH::long_array_var anIDs = aGrp->GetIDs();
6698 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
6703 //================================================================================
6705 \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6706 This method provided for convenience works as DoubleNodes() described above.
6707 \param theElems - list of groups of elements (edges or faces) to be replicated
6708 \param theNodesNot - list of groups of nodes not to replicated
6709 \param theAffectedElems - group of elements to which the replicated nodes
6710 should be associated to.
6711 \return TRUE if operation has been completed successfully, FALSE otherwise
6712 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
6714 //================================================================================
6717 SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
6718 const SMESH::ListOfGroups& theNodesNot,
6719 const SMESH::ListOfGroups& theAffectedElems)
6720 throw (SALOME::SALOME_Exception)
6726 SMESHDS_Mesh* aMeshDS = getMeshDS();
6727 TIDSortedElemSet anElems, aNodes, anAffected;
6728 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6729 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6730 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6732 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6734 // Update Python script
6735 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
6736 << &theNodesNot << ", " << &theAffectedElems << " )";
6738 declareMeshModified( /*isReComputeSafe=*/false );
6741 SMESH_CATCH( SMESH::throwCorbaException );
6745 //================================================================================
6747 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6748 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6749 \param theElems - list of groups of elements (edges or faces) to be replicated
6750 \param theNodesNot - list of groups of nodes not to replicated
6751 \param theAffectedElems - group of elements to which the replicated nodes
6752 should be associated to.
6753 * \return a new group with newly created elements
6754 * \sa DoubleNodeElemGroups()
6756 //================================================================================
6758 SMESH::SMESH_Group_ptr
6759 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
6760 const SMESH::ListOfGroups& theNodesNot,
6761 const SMESH::ListOfGroups& theAffectedElems)
6762 throw (SALOME::SALOME_Exception)
6765 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
6769 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6770 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6772 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
6774 << theNodesNot << ", "
6775 << theAffectedElems << " )";
6777 return elemGroup._retn();
6780 //================================================================================
6782 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6783 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6784 \param theElems - list of groups of elements (edges or faces) to be replicated
6785 \param theNodesNot - list of groups of nodes not to replicated
6786 \param theAffectedElems - group of elements to which the replicated nodes
6787 should be associated to.
6788 * \return a new group with newly created elements
6789 * \sa DoubleNodeElemGroups()
6791 //================================================================================
6793 SMESH::ListOfGroups*
6794 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
6795 const SMESH::ListOfGroups& theNodesNot,
6796 const SMESH::ListOfGroups& theAffectedElems,
6797 CORBA::Boolean theElemGroupNeeded,
6798 CORBA::Boolean theNodeGroupNeeded)
6799 throw (SALOME::SALOME_Exception)
6802 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6803 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6804 aTwoGroups->length( 2 );
6809 SMESHDS_Mesh* aMeshDS = getMeshDS();
6810 TIDSortedElemSet anElems, aNodes, anAffected;
6811 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6812 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6813 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6815 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6817 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6822 // Create group with newly created elements
6823 CORBA::String_var elemGroupName = theElems[0]->GetName();
6824 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6825 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6827 SMESH::long_array_var anIds = GetLastCreatedElems();
6828 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6829 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6830 aNewElemGroup->Add(anIds);
6832 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6834 SMESH::long_array_var anIds = GetLastCreatedNodes();
6835 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6836 aNewNodeGroup->Add(anIds);
6840 // Update Python script
6843 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6844 else pyDump << aNewElemGroup << ", ";
6845 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6846 else pyDump << aNewNodeGroup << " ] = ";
6848 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6849 << &theNodesNot << ", "
6850 << &theAffectedElems << ", "
6851 << theElemGroupNeeded << ", "
6852 << theNodeGroupNeeded << " )";
6854 aTwoGroups[0] = aNewElemGroup._retn();
6855 aTwoGroups[1] = aNewNodeGroup._retn();
6856 return aTwoGroups._retn();
6858 SMESH_CATCH( SMESH::throwCorbaException );
6862 //================================================================================
6864 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6865 This method provided for convenience works as DoubleNodes() described above.
6866 \param theElems - list of groups of elements (edges or faces) to be replicated
6867 \param theNodesNot - list of groups of nodes not to replicated
6868 \param theShape - shape to detect affected elements (element which geometric center
6869 located on or inside shape).
6870 The replicated nodes should be associated to affected elements.
6871 \return TRUE if operation has been completed successfully, FALSE otherwise
6872 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6874 //================================================================================
6877 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6878 const SMESH::ListOfGroups& theNodesNot,
6879 GEOM::GEOM_Object_ptr theShape )
6880 throw (SALOME::SALOME_Exception)
6886 SMESHDS_Mesh* aMeshDS = getMeshDS();
6887 TIDSortedElemSet anElems, aNodes;
6888 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6889 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6891 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6892 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6894 // Update Python script
6895 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6896 << &theNodesNot << ", " << theShape << " )";
6898 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6901 SMESH_CATCH( SMESH::throwCorbaException );
6905 //================================================================================
6907 \brief Identify the elements that will be affected by node duplication (actual
6908 duplication is not performed.
6909 This method is the first step of DoubleNodeElemGroupsInRegion.
6910 \param theElems - list of groups of elements (edges or faces) to be replicated
6911 \param theNodesNot - list of groups of nodes not to replicated
6912 \param theShape - shape to detect affected elements (element which geometric center
6913 located on or inside shape).
6914 The replicated nodes should be associated to affected elements.
6915 \return groups of affected elements
6916 \sa DoubleNodeElemGroupsInRegion()
6918 //================================================================================
6919 SMESH::ListOfGroups*
6920 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6921 const SMESH::ListOfGroups& theNodesNot,
6922 GEOM::GEOM_Object_ptr theShape )
6923 throw (SALOME::SALOME_Exception)
6926 MESSAGE("AffectedElemGroupsInRegion");
6927 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6928 bool isEdgeGroup = false;
6929 bool isFaceGroup = false;
6930 bool isVolumeGroup = false;
6931 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6932 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6933 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6937 ::SMESH_MeshEditor aMeshEditor(myMesh);
6939 SMESHDS_Mesh* aMeshDS = getMeshDS();
6940 TIDSortedElemSet anElems, aNodes;
6941 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6942 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6944 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6945 TIDSortedElemSet anAffected;
6946 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6949 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6954 int lg = anAffected.size();
6955 MESSAGE("lg="<< lg);
6956 SMESH::long_array_var volumeIds = new SMESH::long_array;
6957 volumeIds->length(lg);
6958 SMESH::long_array_var faceIds = new SMESH::long_array;
6959 faceIds->length(lg);
6960 SMESH::long_array_var edgeIds = new SMESH::long_array;
6961 edgeIds->length(lg);
6966 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6967 for (; eIt != anAffected.end(); ++eIt)
6969 const SMDS_MeshElement* anElem = *eIt;
6972 int elemId = anElem->GetID();
6973 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6974 volumeIds[ivol++] = elemId;
6975 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6976 faceIds[iface++] = elemId;
6977 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6978 edgeIds[iedge++] = elemId;
6980 volumeIds->length(ivol);
6981 faceIds->length(iface);
6982 edgeIds->length(iedge);
6984 aNewVolumeGroup->Add(volumeIds);
6985 aNewFaceGroup->Add(faceIds);
6986 aNewEdgeGroup->Add(edgeIds);
6987 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6988 isFaceGroup = (aNewFaceGroup->Size() > 0);
6989 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6993 if (isEdgeGroup) nbGroups++;
6994 if (isFaceGroup) nbGroups++;
6995 if (isVolumeGroup) nbGroups++;
6996 aListOfGroups->length(nbGroups);
6999 if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
7000 if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
7001 if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
7003 // Update Python script
7006 if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
7007 if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
7008 if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
7010 pyDump << this << ".AffectedElemGroupsInRegion( "
7011 << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
7013 return aListOfGroups._retn();
7015 SMESH_CATCH( SMESH::throwCorbaException );
7019 //================================================================================
7021 \brief Generated skin mesh (containing 2D cells) from 3D mesh
7022 The created 2D mesh elements based on nodes of free faces of boundary volumes
7023 \return TRUE if operation has been completed successfully, FALSE otherwise
7025 //================================================================================
7027 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
7028 throw (SALOME::SALOME_Exception)
7033 bool aResult = getEditor().Make2DMeshFrom3D();
7035 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
7037 declareMeshModified( /*isReComputeSafe=*/ !aResult );
7040 SMESH_CATCH( SMESH::throwCorbaException );
7044 //================================================================================
7046 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
7047 * The list of groups must contain at least two groups. The groups have to be disjoint:
7048 * no common element into two different groups.
7049 * The nodes of the internal faces at the boundaries of the groups are doubled.
7050 * Optionally, the internal faces are replaced by flat elements.
7051 * Triangles are transformed into prisms, and quadrangles into hexahedrons.
7052 * The flat elements are stored in groups of volumes.
7053 * These groups are named according to the position of the group in the list:
7054 * 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.
7055 * 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.
7056 * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
7057 * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
7058 * \param theDomains - list of groups of volumes
7059 * \param createJointElems - if TRUE, create the elements
7060 * \param onAllBoundaries - if TRUE, the nodes and elements are also created on
7061 * the boundary between \a theDomains and the rest mesh
7062 * \return TRUE if operation has been completed successfully, FALSE otherwise
7064 //================================================================================
7067 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
7068 CORBA::Boolean createJointElems,
7069 CORBA::Boolean onAllBoundaries )
7070 throw (SALOME::SALOME_Exception)
7077 SMESHDS_Mesh* aMeshDS = getMeshDS();
7079 // MESSAGE("theDomains.length = "<<theDomains.length());
7080 if ( theDomains.length() <= 1 && !onAllBoundaries )
7081 THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
7083 vector<TIDSortedElemSet> domains;
7084 domains.resize( theDomains.length() );
7086 for ( int i = 0, n = theDomains.length(); i < n; i++ )
7088 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
7089 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
7091 // if ( aGrp->GetType() != SMESH::VOLUME )
7092 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
7093 SMESH::long_array_var anIDs = aGrp->GetIDs();
7094 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
7098 isOK = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems, onAllBoundaries );
7099 // TODO publish the groups of flat elements in study
7101 declareMeshModified( /*isReComputeSafe=*/ !isOK );
7103 // Update Python script
7104 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
7105 << ", " << createJointElems << ", " << onAllBoundaries << " )";
7107 SMESH_CATCH( SMESH::throwCorbaException );
7109 myMesh_i->CreateGroupServants(); // publish created groups if any
7114 //================================================================================
7116 * \brief Double nodes on some external faces and create flat elements.
7117 * Flat elements are mainly used by some types of mechanic calculations.
7119 * Each group of the list must be constituted of faces.
7120 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
7121 * @param theGroupsOfFaces - list of groups of faces
7122 * @return TRUE if operation has been completed successfully, FALSE otherwise
7124 //================================================================================
7127 SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
7128 throw (SALOME::SALOME_Exception)
7133 SMESHDS_Mesh* aMeshDS = getMeshDS();
7135 vector<TIDSortedElemSet> faceGroups;
7138 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
7140 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
7141 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
7143 TIDSortedElemSet faceGroup;
7145 faceGroups.push_back(faceGroup);
7146 SMESH::long_array_var anIDs = aGrp->GetIDs();
7147 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
7151 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
7152 // TODO publish the groups of flat elements in study
7154 declareMeshModified( /*isReComputeSafe=*/ !aResult );
7156 // Update Python script
7157 TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
7160 SMESH_CATCH( SMESH::throwCorbaException );
7164 //================================================================================
7166 * \brief Identify all the elements around a geom shape, get the faces delimiting
7169 * Build groups of volume to remove, groups of faces to replace on the skin of the
7170 * object, groups of faces to remove inside the object, (idem edges).
7171 * Build ordered list of nodes at the border of each group of faces to replace
7172 * (to be used to build a geom subshape).
7174 //================================================================================
7176 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
7177 GEOM::GEOM_Object_ptr theShape,
7178 const char* groupName,
7179 const SMESH::double_array& theNodesCoords,
7180 SMESH::array_of_long_array_out GroupsOfNodes)
7181 throw (SALOME::SALOME_Exception)
7186 std::vector<std::vector<int> > aListOfListOfNodes;
7187 ::SMESH_MeshEditor aMeshEditor( myMesh );
7189 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
7190 if ( !theNodeSearcher )
7191 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
7193 vector<double> nodesCoords;
7194 for (int i = 0; i < theNodesCoords.length(); i++)
7196 nodesCoords.push_back( theNodesCoords[i] );
7199 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
7200 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
7201 nodesCoords, aListOfListOfNodes);
7203 GroupsOfNodes = new SMESH::array_of_long_array;
7204 GroupsOfNodes->length( aListOfListOfNodes.size() );
7205 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
7206 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
7208 vector<int>& aListOfNodes = *llIt;
7209 vector<int>::iterator lIt = aListOfNodes.begin();;
7210 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
7211 aGroup.length( aListOfNodes.size() );
7212 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
7213 aGroup[ j ] = (*lIt);
7215 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
7218 << ", '" << groupName << "', "
7219 << theNodesCoords << " )";
7221 SMESH_CATCH( SMESH::throwCorbaException );
7224 // issue 20749 ===================================================================
7226 * \brief Creates missing boundary elements
7227 * \param elements - elements whose boundary is to be checked
7228 * \param dimension - defines type of boundary elements to create
7229 * \param groupName - a name of group to store created boundary elements in,
7230 * "" means not to create the group
7231 * \param meshName - a name of new mesh to store created boundary elements in,
7232 * "" means not to create the new mesh
7233 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
7234 * \param toCopyExistingBondary - if true, not only new but also pre-existing
7235 * boundary elements will be copied into the new mesh
7236 * \param group - returns the create group, if any
7237 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
7239 // ================================================================================
7241 SMESH::SMESH_Mesh_ptr
7242 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
7243 SMESH::Bnd_Dimension dim,
7244 const char* groupName,
7245 const char* meshName,
7246 CORBA::Boolean toCopyElements,
7247 CORBA::Boolean toCopyExistingBondary,
7248 SMESH::SMESH_Group_out group)
7249 throw (SALOME::SALOME_Exception)
7254 if ( dim > SMESH::BND_1DFROM2D )
7255 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7257 SMESHDS_Mesh* aMeshDS = getMeshDS();
7259 SMESH::SMESH_Mesh_var mesh_var;
7260 SMESH::SMESH_Group_var group_var;
7264 TIDSortedElemSet elements;
7265 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
7266 prepareIdSource( idSource );
7267 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
7271 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
7272 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7274 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
7276 // group of new boundary elements
7277 SMESH_Group* smesh_group = 0;
7278 if ( strlen(groupName) )
7280 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
7281 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7282 smesh_group = group_i->GetSmeshGroup();
7286 getEditor().MakeBoundaryMesh( elements,
7287 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7291 toCopyExistingBondary);
7294 smesh_mesh->GetMeshDS()->Modified();
7297 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7299 // result of MakeBoundaryMesh() is a tuple (mesh, group)
7300 if ( mesh_var->_is_nil() )
7301 pyDump << myMesh_i->_this() << ", ";
7303 pyDump << mesh_var << ", ";
7304 if ( group_var->_is_nil() )
7305 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7307 pyDump << group_var << " = ";
7308 pyDump << this << ".MakeBoundaryMesh( "
7310 << "SMESH." << dimName[int(dim)] << ", "
7311 << "'" << groupName << "', "
7312 << "'" << meshName<< "', "
7313 << toCopyElements << ", "
7314 << toCopyExistingBondary << ")";
7316 group = group_var._retn();
7317 return mesh_var._retn();
7319 SMESH_CATCH( SMESH::throwCorbaException );
7320 return SMESH::SMESH_Mesh::_nil();
7323 //================================================================================
7325 * \brief Creates missing boundary elements
7326 * \param dimension - defines type of boundary elements to create
7327 * \param groupName - a name of group to store all boundary elements in,
7328 * "" means not to create the group
7329 * \param meshName - a name of a new mesh, which is a copy of the initial
7330 * mesh + created boundary elements; "" means not to create the new mesh
7331 * \param toCopyAll - if true, the whole initial mesh will be copied into
7332 * the new mesh else only boundary elements will be copied into the new mesh
7333 * \param groups - optional groups of elements to make boundary around
7334 * \param mesh - returns the mesh where elements were added to
7335 * \param group - returns the created group, if any
7336 * \retval long - number of added boundary elements
7338 //================================================================================
7340 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
7341 const char* groupName,
7342 const char* meshName,
7343 CORBA::Boolean toCopyAll,
7344 const SMESH::ListOfIDSources& groups,
7345 SMESH::SMESH_Mesh_out mesh,
7346 SMESH::SMESH_Group_out group)
7347 throw (SALOME::SALOME_Exception)
7352 if ( dim > SMESH::BND_1DFROM2D )
7353 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7355 // separate groups belonging to this and other mesh
7356 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
7357 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
7358 groupsOfThisMesh->length( groups.length() );
7359 groupsOfOtherMesh->length( groups.length() );
7360 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
7361 for ( int i = 0; i < groups.length(); ++i )
7363 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
7364 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
7365 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
7367 groupsOfThisMesh[ nbGroups++ ] = groups[i];
7368 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
7369 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
7371 groupsOfThisMesh->length( nbGroups );
7372 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
7377 if ( nbGroupsOfOtherMesh > 0 )
7379 // process groups belonging to another mesh
7380 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
7381 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
7382 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
7383 groupsOfOtherMesh, mesh, group );
7386 SMESH::SMESH_Mesh_var mesh_var;
7387 SMESH::SMESH_Group_var group_var;
7390 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
7391 const bool toCopyMesh = ( strlen( meshName ) > 0 );
7395 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
7397 /*toCopyGroups=*/false,
7398 /*toKeepIDs=*/true);
7400 mesh_var = makeMesh(meshName);
7402 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7403 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
7406 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
7407 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
7409 // group of boundary elements
7410 SMESH_Group* smesh_group = 0;
7411 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
7412 if ( strlen(groupName) )
7414 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
7415 group_var = mesh_i->CreateGroup( groupType, groupName );
7416 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7417 smesh_group = group_i->GetSmeshGroup();
7420 TIDSortedElemSet elements;
7422 if ( groups.length() > 0 )
7424 for ( int i = 0; i < nbGroups; ++i )
7427 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
7429 SMESH::Bnd_Dimension bdim =
7430 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
7431 nbAdded += getEditor().MakeBoundaryMesh( elements,
7432 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
7435 /*toCopyElements=*/false,
7436 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7437 /*toAddExistingBondary=*/true,
7438 /*aroundElements=*/true);
7444 nbAdded += getEditor().MakeBoundaryMesh( elements,
7445 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7448 /*toCopyElements=*/false,
7449 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7450 /*toAddExistingBondary=*/true);
7452 tgtMesh->GetMeshDS()->Modified();
7454 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7456 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
7457 pyDump << "nbAdded, ";
7458 if ( mesh_var->_is_nil() )
7459 pyDump << myMesh_i->_this() << ", ";
7461 pyDump << mesh_var << ", ";
7462 if ( group_var->_is_nil() )
7463 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7465 pyDump << group_var << " = ";
7466 pyDump << this << ".MakeBoundaryElements( "
7467 << "SMESH." << dimName[int(dim)] << ", "
7468 << "'" << groupName << "', "
7469 << "'" << meshName<< "', "
7470 << toCopyAll << ", "
7473 mesh = mesh_var._retn();
7474 group = group_var._retn();
7477 SMESH_CATCH( SMESH::throwCorbaException );