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();
786 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
787 SMESH::ElementType type)
789 _IDSource* idSrc = new _IDSource;
790 idSrc->_mesh = myMesh_i->_this();
793 if ( type == SMESH::ALL && ids.length() > 0 )
794 idSrc->_type = myMesh_i->GetElementType( ids[0], true );
796 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
798 return anIDSourceVar._retn();
801 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
803 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
806 CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource,
809 if ( _IDSource* tmpIdSource = SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource ))
811 nbIds = (int) tmpIdSource->_ids.length();
812 return & tmpIdSource->_ids[0];
818 // void SMESH_MeshEditor_i::deleteAuxIDSources()
820 // std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
821 // for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
823 // myAuxIDSources.clear();
826 //=============================================================================
830 //=============================================================================
833 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
834 throw (SALOME::SALOME_Exception)
841 for (int i = 0; i < IDsOfElements.length(); i++)
842 IdList.push_back( IDsOfElements[i] );
844 // Update Python script
845 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
848 bool ret = getEditor().Remove( IdList, false );
850 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
853 SMESH_CATCH( SMESH::throwCorbaException );
857 //=============================================================================
861 //=============================================================================
863 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
864 throw (SALOME::SALOME_Exception)
870 for (int i = 0; i < IDsOfNodes.length(); i++)
871 IdList.push_back( IDsOfNodes[i] );
873 // Update Python script
874 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
876 bool ret = getEditor().Remove( IdList, true );
878 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
881 SMESH_CATCH( SMESH::throwCorbaException );
885 //=============================================================================
889 //=============================================================================
891 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
892 throw (SALOME::SALOME_Exception)
897 // Update Python script
898 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
900 // Create filter to find all orphan nodes
901 SMESH::Controls::Filter::TIdSequence seq;
902 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
903 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
905 // remove orphan nodes (if there are any)
907 for ( int i = 0; i < seq.size(); i++ )
908 IdList.push_back( seq[i] );
910 int nbNodesBefore = myMesh->NbNodes();
911 getEditor().Remove( IdList, true );
912 int nbNodesAfter = myMesh->NbNodes();
914 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
915 return nbNodesBefore - nbNodesAfter;
917 SMESH_CATCH( SMESH::throwCorbaException );
921 //=============================================================================
925 //=============================================================================
927 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
928 throw (SALOME::SALOME_Exception)
933 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
935 // Update Python script
936 TPythonDump() << "nodeID = " << this << ".AddNode( "
937 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
939 declareMeshModified( /*isReComputeSafe=*/false );
942 SMESH_CATCH( SMESH::throwCorbaException );
946 //=============================================================================
948 * Create 0D element on the given node.
950 //=============================================================================
952 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
953 throw (SALOME::SALOME_Exception)
958 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
959 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
961 // Update Python script
962 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
964 declareMeshModified( /*isReComputeSafe=*/false );
966 return elem ? elem->GetID() : 0;
968 SMESH_CATCH( SMESH::throwCorbaException );
972 //=============================================================================
974 * Create a ball element on the given node.
976 //=============================================================================
978 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
979 throw (SALOME::SALOME_Exception)
984 if ( diameter < std::numeric_limits<double>::min() )
985 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
987 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
988 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
990 // Update Python script
991 TPythonDump() << "ballElem = "
992 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
994 declareMeshModified( /*isReComputeSafe=*/false );
995 return elem ? elem->GetID() : 0;
997 SMESH_CATCH( SMESH::throwCorbaException );
1001 //=============================================================================
1003 * Create an edge, either linear and quadratic (this is determed
1004 * by number of given nodes, two or three)
1006 //=============================================================================
1008 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
1009 throw (SALOME::SALOME_Exception)
1014 int NbNodes = IDsOfNodes.length();
1015 SMDS_MeshElement* elem = 0;
1018 CORBA::Long index1 = IDsOfNodes[0];
1019 CORBA::Long index2 = IDsOfNodes[1];
1020 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
1021 getMeshDS()->FindNode(index2));
1023 // Update Python script
1024 TPythonDump() << "edge = " << this << ".AddEdge([ "
1025 << index1 << ", " << index2 <<" ])";
1028 CORBA::Long n1 = IDsOfNodes[0];
1029 CORBA::Long n2 = IDsOfNodes[1];
1030 CORBA::Long n12 = IDsOfNodes[2];
1031 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
1032 getMeshDS()->FindNode(n2),
1033 getMeshDS()->FindNode(n12));
1034 // Update Python script
1035 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
1036 <<n1<<", "<<n2<<", "<<n12<<" ])";
1039 declareMeshModified( /*isReComputeSafe=*/false );
1040 return elem ? elem->GetID() : 0;
1042 SMESH_CATCH( SMESH::throwCorbaException );
1046 //=============================================================================
1050 //=============================================================================
1052 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1053 throw (SALOME::SALOME_Exception)
1058 int NbNodes = IDsOfNodes.length();
1064 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1065 for (int i = 0; i < NbNodes; i++)
1066 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1068 SMDS_MeshElement* elem = 0;
1070 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1071 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1072 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1073 nodes[4], nodes[5]); break;
1074 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1075 nodes[4], nodes[5], nodes[6]); break;
1076 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1077 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1078 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1079 nodes[4], nodes[5], nodes[6], nodes[7],
1081 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1084 // Update Python script
1085 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1087 declareMeshModified( /*isReComputeSafe=*/false );
1089 return elem ? elem->GetID() : 0;
1091 SMESH_CATCH( SMESH::throwCorbaException );
1095 //=============================================================================
1099 //=============================================================================
1100 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1101 throw (SALOME::SALOME_Exception)
1106 int NbNodes = IDsOfNodes.length();
1107 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1108 for (int i = 0; i < NbNodes; i++)
1109 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1111 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1113 // Update Python script
1114 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1116 declareMeshModified( /*isReComputeSafe=*/false );
1117 return elem ? elem->GetID() : 0;
1119 SMESH_CATCH( SMESH::throwCorbaException );
1123 //=============================================================================
1125 * Create volume, either linear and quadratic (this is determed
1126 * by number of given nodes)
1128 //=============================================================================
1130 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1131 throw (SALOME::SALOME_Exception)
1136 int NbNodes = IDsOfNodes.length();
1137 vector< const SMDS_MeshNode*> n(NbNodes);
1138 for(int i=0;i<NbNodes;i++)
1139 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1141 SMDS_MeshElement* elem = 0;
1144 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1145 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1146 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1147 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1148 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1149 n[6],n[7],n[8],n[9]);
1151 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1152 n[6],n[7],n[8],n[9],n[10],n[11]);
1154 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1155 n[7],n[8],n[9],n[10],n[11],n[12]);
1157 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1158 n[9],n[10],n[11],n[12],n[13],n[14]);
1160 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1161 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1162 n[15],n[16],n[17],n[18],n[19]);
1164 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1165 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1166 n[15],n[16],n[17],n[18],n[19],
1167 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1171 // Update Python script
1172 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1174 declareMeshModified( /*isReComputeSafe=*/false );
1175 return elem ? elem->GetID() : 0;
1177 SMESH_CATCH( SMESH::throwCorbaException );
1181 //=============================================================================
1183 * AddPolyhedralVolume
1185 //=============================================================================
1186 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1187 const SMESH::long_array & Quantities)
1188 throw (SALOME::SALOME_Exception)
1193 int NbNodes = IDsOfNodes.length();
1194 std::vector<const SMDS_MeshNode*> n (NbNodes);
1195 for (int i = 0; i < NbNodes; i++)
1197 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1198 if (!aNode) return 0;
1202 int NbFaces = Quantities.length();
1203 std::vector<int> q (NbFaces);
1204 for (int j = 0; j < NbFaces; j++)
1205 q[j] = Quantities[j];
1207 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1209 // Update Python script
1210 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1211 << IDsOfNodes << ", " << Quantities << " )";
1213 declareMeshModified( /*isReComputeSafe=*/false );
1214 return elem ? elem->GetID() : 0;
1216 SMESH_CATCH( SMESH::throwCorbaException );
1220 //=============================================================================
1222 * AddPolyhedralVolumeByFaces
1224 //=============================================================================
1226 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1227 throw (SALOME::SALOME_Exception)
1232 int NbFaces = IdsOfFaces.length();
1233 std::vector<const SMDS_MeshNode*> poly_nodes;
1234 std::vector<int> quantities (NbFaces);
1236 for (int i = 0; i < NbFaces; i++) {
1237 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1238 quantities[i] = aFace->NbNodes();
1240 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1241 while (It->more()) {
1242 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1246 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1248 // Update Python script
1249 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1250 << IdsOfFaces << " )";
1252 declareMeshModified( /*isReComputeSafe=*/false );
1253 return elem ? elem->GetID() : 0;
1255 SMESH_CATCH( SMESH::throwCorbaException );
1259 //=============================================================================
1261 // \brief Create 0D elements on all nodes of the given object except those
1262 // nodes on which a 0D element already exists.
1263 // \param theObject object on whose nodes 0D elements will be created.
1264 // \param theGroupName optional name of a group to add 0D elements created
1265 // and/or found on nodes of \a theObject.
1266 // \return an object (a new group or a temporary SMESH_IDSource) holding
1267 // ids of new and/or found 0D elements.
1269 //=============================================================================
1271 SMESH::SMESH_IDSource_ptr
1272 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1273 const char* theGroupName)
1274 throw (SALOME::SALOME_Exception)
1279 SMESH::SMESH_IDSource_var result;
1282 TIDSortedElemSet elements, elems0D;
1283 prepareIdSource( theObject );
1284 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1285 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1287 SMESH::long_array_var newElems = new SMESH::long_array;
1288 newElems->length( elems0D.size() );
1289 TIDSortedElemSet::iterator eIt = elems0D.begin();
1290 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1291 newElems[ i ] = (*eIt)->GetID();
1293 SMESH::SMESH_GroupBase_var groupToFill;
1294 if ( theGroupName && strlen( theGroupName ))
1296 // Get existing group named theGroupName
1297 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1298 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1299 SMESH::SMESH_GroupBase_var group = groups[i];
1300 if ( !group->_is_nil() ) {
1301 CORBA::String_var name = group->GetName();
1302 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1303 groupToFill = group;
1308 if ( groupToFill->_is_nil() )
1309 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1310 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1311 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1314 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1316 group_i->Add( newElems );
1317 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1318 pyDump << groupToFill;
1322 result = MakeIDSource( newElems, SMESH::ELEM0D );
1323 pyDump << "elem0DIDs";
1326 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1327 << theObject << ", '" << theGroupName << "' )";
1329 return result._retn();
1331 SMESH_CATCH( SMESH::throwCorbaException );
1335 //=============================================================================
1337 * \brief Bind a node to a vertex
1338 * \param NodeID - node ID
1339 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1340 * \retval boolean - false if NodeID or VertexID is invalid
1342 //=============================================================================
1344 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1345 throw (SALOME::SALOME_Exception)
1349 SMESHDS_Mesh * mesh = getMeshDS();
1350 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1352 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1354 if ( mesh->MaxShapeIndex() < VertexID )
1355 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1357 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1358 if ( shape.ShapeType() != TopAbs_VERTEX )
1359 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1361 mesh->SetNodeOnVertex( node, VertexID );
1363 myMesh->SetIsModified( true );
1365 SMESH_CATCH( SMESH::throwCorbaException );
1368 //=============================================================================
1370 * \brief Store node position on an edge
1371 * \param NodeID - node ID
1372 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1373 * \param paramOnEdge - parameter on edge where the node is located
1374 * \retval boolean - false if any parameter is invalid
1376 //=============================================================================
1378 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1379 CORBA::Double paramOnEdge)
1380 throw (SALOME::SALOME_Exception)
1384 SMESHDS_Mesh * mesh = getMeshDS();
1385 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1387 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1389 if ( mesh->MaxShapeIndex() < EdgeID )
1390 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1392 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1393 if ( shape.ShapeType() != TopAbs_EDGE )
1394 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1397 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1398 if ( paramOnEdge < f || paramOnEdge > l )
1399 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1401 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1403 myMesh->SetIsModified( true );
1405 SMESH_CATCH( SMESH::throwCorbaException );
1408 //=============================================================================
1410 * \brief Store node position on a face
1411 * \param NodeID - node ID
1412 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1413 * \param u - U parameter on face where the node is located
1414 * \param v - V parameter on face where the node is located
1415 * \retval boolean - false if any parameter is invalid
1417 //=============================================================================
1419 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1420 CORBA::Double u, CORBA::Double v)
1421 throw (SALOME::SALOME_Exception)
1424 SMESHDS_Mesh * mesh = getMeshDS();
1425 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1427 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1429 if ( mesh->MaxShapeIndex() < FaceID )
1430 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1432 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1433 if ( shape.ShapeType() != TopAbs_FACE )
1434 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1436 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1437 bool isOut = ( u < surf.FirstUParameter() ||
1438 u > surf.LastUParameter() ||
1439 v < surf.FirstVParameter() ||
1440 v > surf.LastVParameter() );
1444 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1445 << " u( " << surf.FirstUParameter()
1446 << "," << surf.LastUParameter()
1447 << ") v( " << surf.FirstVParameter()
1448 << "," << surf.LastVParameter() << ")" );
1450 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1453 mesh->SetNodeOnFace( node, FaceID, u, v );
1454 myMesh->SetIsModified( true );
1456 SMESH_CATCH( SMESH::throwCorbaException );
1459 //=============================================================================
1461 * \brief Bind a node to a solid
1462 * \param NodeID - node ID
1463 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1464 * \retval boolean - false if NodeID or SolidID is invalid
1466 //=============================================================================
1468 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1469 throw (SALOME::SALOME_Exception)
1472 SMESHDS_Mesh * mesh = getMeshDS();
1473 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1475 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1477 if ( mesh->MaxShapeIndex() < SolidID )
1478 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1480 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1481 if ( shape.ShapeType() != TopAbs_SOLID &&
1482 shape.ShapeType() != TopAbs_SHELL)
1483 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1485 mesh->SetNodeInVolume( node, SolidID );
1487 SMESH_CATCH( SMESH::throwCorbaException );
1490 //=============================================================================
1492 * \brief Bind an element to a shape
1493 * \param ElementID - element ID
1494 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1496 //=============================================================================
1498 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1499 CORBA::Long ShapeID)
1500 throw (SALOME::SALOME_Exception)
1503 SMESHDS_Mesh * mesh = getMeshDS();
1504 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1506 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1508 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1509 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1511 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1512 if ( shape.ShapeType() != TopAbs_EDGE &&
1513 shape.ShapeType() != TopAbs_FACE &&
1514 shape.ShapeType() != TopAbs_SOLID &&
1515 shape.ShapeType() != TopAbs_SHELL )
1516 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1518 mesh->SetMeshElementOnShape( elem, ShapeID );
1520 myMesh->SetIsModified( true );
1522 SMESH_CATCH( SMESH::throwCorbaException );
1525 //=============================================================================
1529 //=============================================================================
1531 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1532 CORBA::Long NodeID2)
1533 throw (SALOME::SALOME_Exception)
1538 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1539 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1543 // Update Python script
1544 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1545 << NodeID1 << ", " << NodeID2 << " )";
1547 int ret = getEditor().InverseDiag ( n1, n2 );
1549 declareMeshModified( /*isReComputeSafe=*/false );
1552 SMESH_CATCH( SMESH::throwCorbaException );
1556 //=============================================================================
1560 //=============================================================================
1562 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1563 CORBA::Long NodeID2)
1564 throw (SALOME::SALOME_Exception)
1569 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1570 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1574 // Update Python script
1575 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1576 << NodeID1 << ", " << NodeID2 << " )";
1579 bool stat = getEditor().DeleteDiag ( n1, n2 );
1581 declareMeshModified( /*isReComputeSafe=*/!stat );
1585 SMESH_CATCH( SMESH::throwCorbaException );
1589 //=============================================================================
1593 //=============================================================================
1595 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1596 throw (SALOME::SALOME_Exception)
1601 for (int i = 0; i < IDsOfElements.length(); i++)
1603 CORBA::Long index = IDsOfElements[i];
1604 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1606 getEditor().Reorient( elem );
1608 // Update Python script
1609 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1611 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1614 SMESH_CATCH( SMESH::throwCorbaException );
1618 //=============================================================================
1622 //=============================================================================
1624 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1625 throw (SALOME::SALOME_Exception)
1630 TPythonDump aTPythonDump; // suppress dump in Reorient()
1632 prepareIdSource( theObject );
1634 SMESH::long_array_var anElementsId = theObject->GetIDs();
1635 CORBA::Boolean isDone = Reorient(anElementsId);
1637 // Update Python script
1638 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1640 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1643 SMESH_CATCH( SMESH::throwCorbaException );
1647 //=======================================================================
1648 //function : Reorient2D
1649 //purpose : Reorient faces contained in \a the2Dgroup.
1650 // the2Dgroup - the mesh or its part to reorient
1651 // theDirection - desired direction of normal of \a theFace
1652 // theFace - ID of face whose orientation is checked.
1653 // It can be < 1 then \a thePoint is used to find a face.
1654 // thePoint - is used to find a face if \a theFace < 1.
1655 // return number of reoriented elements.
1656 //=======================================================================
1658 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1659 const SMESH::DirStruct& theDirection,
1660 CORBA::Long theFace,
1661 const SMESH::PointStruct& thePoint)
1662 throw (SALOME::SALOME_Exception)
1665 initData(/*deleteSearchers=*/false);
1667 TIDSortedElemSet elements;
1668 prepareIdSource( the2Dgroup );
1669 IDSource_Error error;
1670 idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1671 if ( error == IDSource_EMPTY )
1673 if ( error == IDSource_INVALID )
1674 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1677 const SMDS_MeshElement* face = 0;
1680 face = getMeshDS()->FindElement( theFace );
1682 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1683 if ( face->GetType() != SMDSAbs_Face )
1684 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1688 // create theElementSearcher if needed
1689 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1690 if ( !theElementSearcher )
1692 if ( elements.empty() ) // search in the whole mesh
1694 if ( myMesh->NbFaces() == 0 )
1695 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1697 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1701 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1702 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1704 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1708 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1709 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1712 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1713 if ( !elements.empty() && !elements.count( face ))
1714 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1717 const SMESH::PointStruct * P = &theDirection.PS;
1718 gp_Vec dirVec( P->x, P->y, P->z );
1719 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1720 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1722 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1725 declareMeshModified( /*isReComputeSafe=*/false );
1727 TPythonDump() << this << ".Reorient2D( "
1728 << the2Dgroup << ", "
1729 << theDirection << ", "
1731 << thePoint << " )";
1735 SMESH_CATCH( SMESH::throwCorbaException );
1739 //=======================================================================
1740 //function : Reorient2DBy3D
1741 //purpose : Reorient faces basing on orientation of adjacent volumes.
1742 //=======================================================================
1744 CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& faceGroups,
1745 SMESH::SMESH_IDSource_ptr volumeGroup,
1746 CORBA::Boolean outsideNormal)
1747 throw (SALOME::SALOME_Exception)
1752 TIDSortedElemSet volumes;
1753 prepareIdSource( volumeGroup );
1754 IDSource_Error volsError;
1755 idSourceToSet( volumeGroup, getMeshDS(), volumes, SMDSAbs_Volume, /*emptyIfMesh=*/1, &volsError);
1758 for ( size_t i = 0; i < faceGroups.length(); ++i )
1760 SMESH::SMESH_IDSource_ptr faceGrp = faceGroups[i].in();
1761 prepareIdSource( faceGrp );
1763 TIDSortedElemSet faces;
1764 IDSource_Error error;
1765 idSourceToSet( faceGrp, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1766 if ( error == IDSource_INVALID && faceGroups.length() == 1 )
1767 THROW_SALOME_CORBA_EXCEPTION("No faces in a given object", SALOME::BAD_PARAM);
1768 if ( error == IDSource_OK && volsError != IDSource_OK )
1769 THROW_SALOME_CORBA_EXCEPTION("No volumes in a given object", SALOME::BAD_PARAM);
1771 nbReori += getEditor().Reorient2DBy3D( faces, volumes, outsideNormal );
1773 if ( error != IDSource_EMPTY && faces.empty() ) // all faces in the mesh treated
1778 declareMeshModified( /*isReComputeSafe=*/false );
1780 TPythonDump() << this << ".Reorient2DBy3D( "
1781 << faceGroups << ", "
1782 << volumeGroup << ", "
1783 << outsideNormal << " )";
1787 SMESH_CATCH( SMESH::throwCorbaException );
1791 //=============================================================================
1793 * \brief Fuse neighbour triangles into quadrangles.
1795 //=============================================================================
1797 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1798 SMESH::NumericalFunctor_ptr Criterion,
1799 CORBA::Double MaxAngle)
1800 throw (SALOME::SALOME_Exception)
1805 SMESHDS_Mesh* aMesh = getMeshDS();
1806 TIDSortedElemSet faces,copyFaces;
1807 SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE);
1808 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter);
1809 TIDSortedElemSet* workElements = & faces;
1811 if ( myIsPreviewMode ) {
1812 SMDSAbs_ElementType select = SMDSAbs_Face;
1813 getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select );
1814 workElements = & copyFaces;
1817 SMESH::NumericalFunctor_i* aNumericalFunctor =
1818 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1819 SMESH::Controls::NumericalFunctorPtr aCrit;
1820 if ( !aNumericalFunctor )
1821 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1823 aCrit = aNumericalFunctor->GetNumericalFunctor();
1825 if ( !myIsPreviewMode ) {
1826 // Update Python script
1827 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1828 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1831 bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle );
1833 declareMeshModified( /*isReComputeSafe=*/!stat );
1836 SMESH_CATCH( SMESH::throwCorbaException );
1840 //=============================================================================
1842 * \brief Fuse neighbour triangles into quadrangles.
1844 //=============================================================================
1846 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1847 SMESH::NumericalFunctor_ptr Criterion,
1848 CORBA::Double MaxAngle)
1849 throw (SALOME::SALOME_Exception)
1854 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1856 prepareIdSource( theObject );
1857 SMESH::long_array_var anElementsId = theObject->GetIDs();
1858 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1860 if ( !myIsPreviewMode ) {
1861 SMESH::NumericalFunctor_i* aNumericalFunctor =
1862 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1864 // Update Python script
1865 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1866 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1871 SMESH_CATCH( SMESH::throwCorbaException );
1875 //=============================================================================
1877 * \brief Split quadrangles into triangles.
1879 //=============================================================================
1881 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1882 SMESH::NumericalFunctor_ptr Criterion)
1883 throw (SALOME::SALOME_Exception)
1888 SMESHDS_Mesh* aMesh = getMeshDS();
1889 TIDSortedElemSet faces;
1890 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1892 SMESH::NumericalFunctor_i* aNumericalFunctor =
1893 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1894 SMESH::Controls::NumericalFunctorPtr aCrit;
1895 if ( !aNumericalFunctor )
1896 aCrit.reset( new SMESH::Controls::AspectRatio() );
1898 aCrit = aNumericalFunctor->GetNumericalFunctor();
1901 // Update Python script
1902 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1904 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1906 declareMeshModified( /*isReComputeSafe=*/false );
1909 SMESH_CATCH( SMESH::throwCorbaException );
1913 //=============================================================================
1915 * \brief Split quadrangles into triangles.
1917 //=============================================================================
1919 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1920 SMESH::NumericalFunctor_ptr Criterion)
1921 throw (SALOME::SALOME_Exception)
1926 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1928 prepareIdSource( theObject );
1929 SMESH::long_array_var anElementsId = theObject->GetIDs();
1930 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1932 SMESH::NumericalFunctor_i* aNumericalFunctor =
1933 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1935 // Update Python script
1936 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1938 declareMeshModified( /*isReComputeSafe=*/false );
1941 SMESH_CATCH( SMESH::throwCorbaException );
1945 //================================================================================
1947 * \brief Split each of quadrangles into 4 triangles.
1948 * \param [in] theObject - theQuads Container of quadrangles to split.
1950 //================================================================================
1952 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1953 throw (SALOME::SALOME_Exception)
1958 TIDSortedElemSet faces;
1959 prepareIdSource( theObject );
1960 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1962 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1964 getEditor().QuadTo4Tri( faces );
1965 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1967 SMESH_CATCH( SMESH::throwCorbaException );
1970 //=============================================================================
1972 * \brief Split quadrangles into triangles.
1974 //=============================================================================
1976 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1977 CORBA::Boolean Diag13)
1978 throw (SALOME::SALOME_Exception)
1983 SMESHDS_Mesh* aMesh = getMeshDS();
1984 TIDSortedElemSet faces;
1985 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1987 // Update Python script
1988 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1989 << IDsOfElements << ", " << Diag13 << " )";
1991 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1993 declareMeshModified( /*isReComputeSafe=*/ !stat );
1996 SMESH_CATCH( SMESH::throwCorbaException );
2000 //=============================================================================
2002 * \brief Split quadrangles into triangles.
2004 //=============================================================================
2006 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
2007 CORBA::Boolean Diag13)
2008 throw (SALOME::SALOME_Exception)
2013 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
2015 prepareIdSource( theObject );
2016 SMESH::long_array_var anElementsId = theObject->GetIDs();
2017 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
2019 // Update Python script
2020 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
2021 << theObject << ", " << Diag13 << " )";
2023 declareMeshModified( /*isReComputeSafe=*/!isDone );
2026 SMESH_CATCH( SMESH::throwCorbaException );
2031 //=============================================================================
2033 * Find better splitting of the given quadrangle.
2034 * \param IDOfQuad ID of the quadrangle to be splitted.
2035 * \param Criterion A criterion to choose a diagonal for splitting.
2036 * \return 1 if 1-3 diagonal is better, 2 if 2-4
2037 * diagonal is better, 0 if error occurs.
2039 //=============================================================================
2041 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
2042 SMESH::NumericalFunctor_ptr Criterion)
2043 throw (SALOME::SALOME_Exception)
2048 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
2049 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
2051 SMESH::NumericalFunctor_i* aNumericalFunctor =
2052 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
2053 SMESH::Controls::NumericalFunctorPtr aCrit;
2054 if (aNumericalFunctor)
2055 aCrit = aNumericalFunctor->GetNumericalFunctor();
2057 aCrit.reset(new SMESH::Controls::AspectRatio());
2059 int id = getEditor().BestSplit(quad, aCrit);
2060 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
2064 SMESH_CATCH( SMESH::throwCorbaException );
2068 //================================================================================
2070 * \brief Split volumic elements into tetrahedrons
2072 //================================================================================
2074 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
2075 CORBA::Short methodFlags)
2076 throw (SALOME::SALOME_Exception)
2080 prepareIdSource( elems );
2082 ::SMESH_MeshEditor::TFacetOfElem elemSet;
2083 const int noneFacet = -1;
2084 SMDS_ElemIteratorPtr volIt = myMesh_i->GetElements( elems, SMESH::VOLUME );
2085 while( volIt->more() )
2086 elemSet.insert( elemSet.end(), make_pair( volIt->next(), noneFacet ));
2088 getEditor().SplitVolumes( elemSet, int( methodFlags ));
2089 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2091 TPythonDump() << this << ".SplitVolumesIntoTetra( "
2092 << elems << ", " << methodFlags << " )";
2094 SMESH_CATCH( SMESH::throwCorbaException );
2097 //================================================================================
2099 * \brief Split hexahedra into triangular prisms
2100 * \param elems - elements to split
2101 * \param facetToSplitNormal - normal used to find a facet of hexahedron
2102 * to split into triangles
2103 * \param methodFlags - flags passing splitting method:
2104 * 1 - split the hexahedron into 2 prisms
2105 * 2 - split the hexahedron into 4 prisms
2107 //================================================================================
2109 void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms (SMESH::SMESH_IDSource_ptr elems,
2110 const SMESH::PointStruct & startHexPoint,
2111 const SMESH::DirStruct& facetToSplitNormal,
2112 CORBA::Short methodFlags,
2113 CORBA::Boolean allDomains)
2114 throw (SALOME::SALOME_Exception)
2118 prepareIdSource( elems );
2120 gp_Ax1 facetNorm( gp_Pnt( startHexPoint.x,
2123 gp_Dir( facetToSplitNormal.PS.x,
2124 facetToSplitNormal.PS.y,
2125 facetToSplitNormal.PS.z ));
2126 TIDSortedElemSet elemSet;
2127 SMESH::long_array_var anElementsId = elems->GetIDs();
2128 SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA );
2129 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter );
2131 ::SMESH_MeshEditor::TFacetOfElem elemFacets;
2132 while ( !elemSet.empty() )
2134 getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets );
2138 ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin();
2139 for ( ; ef != elemFacets.end(); ++ef )
2140 elemSet.erase( ef->first );
2143 if ( methodFlags == 2 )
2144 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS );
2146 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS );
2148 getEditor().SplitVolumes( elemFacets, int( methodFlags ));
2149 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2151 TPythonDump() << this << ".SplitHexahedraIntoPrisms( "
2153 << startHexPoint << ", "
2154 << facetToSplitNormal<< ", "
2155 << methodFlags<< ", "
2156 << allDomains << " )";
2158 SMESH_CATCH( SMESH::throwCorbaException );
2161 //=======================================================================
2164 //=======================================================================
2167 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2168 const SMESH::long_array & IDsOfFixedNodes,
2169 CORBA::Long MaxNbOfIterations,
2170 CORBA::Double MaxAspectRatio,
2171 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2172 throw (SALOME::SALOME_Exception)
2174 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2175 MaxAspectRatio, Method, false );
2179 //=======================================================================
2180 //function : SmoothParametric
2182 //=======================================================================
2185 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2186 const SMESH::long_array & IDsOfFixedNodes,
2187 CORBA::Long MaxNbOfIterations,
2188 CORBA::Double MaxAspectRatio,
2189 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2190 throw (SALOME::SALOME_Exception)
2192 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2193 MaxAspectRatio, Method, true );
2197 //=======================================================================
2198 //function : SmoothObject
2200 //=======================================================================
2203 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2204 const SMESH::long_array & IDsOfFixedNodes,
2205 CORBA::Long MaxNbOfIterations,
2206 CORBA::Double MaxAspectRatio,
2207 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2208 throw (SALOME::SALOME_Exception)
2210 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2211 MaxAspectRatio, Method, false);
2215 //=======================================================================
2216 //function : SmoothParametricObject
2218 //=======================================================================
2221 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2222 const SMESH::long_array & IDsOfFixedNodes,
2223 CORBA::Long MaxNbOfIterations,
2224 CORBA::Double MaxAspectRatio,
2225 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2226 throw (SALOME::SALOME_Exception)
2228 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2229 MaxAspectRatio, Method, true);
2233 //=============================================================================
2237 //=============================================================================
2240 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2241 const SMESH::long_array & IDsOfFixedNodes,
2242 CORBA::Long MaxNbOfIterations,
2243 CORBA::Double MaxAspectRatio,
2244 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2246 throw (SALOME::SALOME_Exception)
2251 SMESHDS_Mesh* aMesh = getMeshDS();
2253 TIDSortedElemSet elements;
2254 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2256 set<const SMDS_MeshNode*> fixedNodes;
2257 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
2258 CORBA::Long index = IDsOfFixedNodes[i];
2259 const SMDS_MeshNode * node = aMesh->FindNode(index);
2261 fixedNodes.insert( node );
2263 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2264 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2265 method = ::SMESH_MeshEditor::CENTROIDAL;
2267 getEditor().Smooth(elements, fixedNodes, method,
2268 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2270 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2272 // Update Python script
2273 TPythonDump() << "isDone = " << this << "."
2274 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2275 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2276 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2277 << "SMESH.SMESH_MeshEditor."
2278 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2279 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2283 SMESH_CATCH( SMESH::throwCorbaException );
2287 //=============================================================================
2291 //=============================================================================
2294 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2295 const SMESH::long_array & IDsOfFixedNodes,
2296 CORBA::Long MaxNbOfIterations,
2297 CORBA::Double MaxAspectRatio,
2298 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2300 throw (SALOME::SALOME_Exception)
2305 TPythonDump aTPythonDump; // suppress dump in smooth()
2307 prepareIdSource( theObject );
2308 SMESH::long_array_var anElementsId = theObject->GetIDs();
2309 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2310 MaxAspectRatio, Method, IsParametric);
2312 // Update Python script
2313 aTPythonDump << "isDone = " << this << "."
2314 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2315 << theObject << ", " << IDsOfFixedNodes << ", "
2316 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2317 << "SMESH.SMESH_MeshEditor."
2318 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2319 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2323 SMESH_CATCH( SMESH::throwCorbaException );
2327 //=============================================================================
2331 //=============================================================================
2333 void SMESH_MeshEditor_i::RenumberNodes()
2334 throw (SALOME::SALOME_Exception)
2337 // Update Python script
2338 TPythonDump() << this << ".RenumberNodes()";
2340 getMeshDS()->Renumber( true );
2342 SMESH_CATCH( SMESH::throwCorbaException );
2345 //=============================================================================
2349 //=============================================================================
2351 void SMESH_MeshEditor_i::RenumberElements()
2352 throw (SALOME::SALOME_Exception)
2355 // Update Python script
2356 TPythonDump() << this << ".RenumberElements()";
2358 getMeshDS()->Renumber( false );
2360 SMESH_CATCH( SMESH::throwCorbaException );
2363 //=======================================================================
2365 * \brief Return groups by their IDs
2367 //=======================================================================
2369 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2370 throw (SALOME::SALOME_Exception)
2375 myMesh_i->CreateGroupServants();
2376 return myMesh_i->GetGroups( *groupIDs );
2378 SMESH_CATCH( SMESH::throwCorbaException );
2382 //=======================================================================
2383 //function : rotationSweep
2385 //=======================================================================
2387 SMESH::ListOfGroups*
2388 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2389 const SMESH::AxisStruct & theAxis,
2390 CORBA::Double theAngleInRadians,
2391 CORBA::Long theNbOfSteps,
2392 CORBA::Double theTolerance,
2393 const bool theMakeGroups,
2394 const SMDSAbs_ElementType theElementType)
2395 throw (SALOME::SALOME_Exception)
2400 TIDSortedElemSet inElements, copyElements;
2401 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2403 TIDSortedElemSet* workElements = & inElements;
2404 bool makeWalls=true;
2405 if ( myIsPreviewMode )
2407 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2408 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2409 workElements = & copyElements;
2410 //makeWalls = false;
2413 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2414 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2416 ::SMESH_MeshEditor::PGroupIDs groupIds =
2417 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2418 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2420 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2422 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2424 SMESH_CATCH( SMESH::throwCorbaException );
2428 //=======================================================================
2429 //function : RotationSweep
2431 //=======================================================================
2433 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2434 const SMESH::AxisStruct & theAxis,
2435 CORBA::Double theAngleInRadians,
2436 CORBA::Long theNbOfSteps,
2437 CORBA::Double theTolerance)
2438 throw (SALOME::SALOME_Exception)
2440 if ( !myIsPreviewMode ) {
2441 TPythonDump() << this << ".RotationSweep( "
2442 << theIDsOfElements << ", "
2444 << TVar( theAngleInRadians ) << ", "
2445 << TVar( theNbOfSteps ) << ", "
2446 << TVar( theTolerance ) << " )";
2448 rotationSweep(theIDsOfElements,
2456 //=======================================================================
2457 //function : RotationSweepMakeGroups
2459 //=======================================================================
2461 SMESH::ListOfGroups*
2462 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2463 const SMESH::AxisStruct& theAxis,
2464 CORBA::Double theAngleInRadians,
2465 CORBA::Long theNbOfSteps,
2466 CORBA::Double theTolerance)
2467 throw (SALOME::SALOME_Exception)
2469 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2471 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2477 if (!myIsPreviewMode) {
2478 dumpGroupsList(aPythonDump, aGroups);
2479 aPythonDump << this << ".RotationSweepMakeGroups( "
2480 << theIDsOfElements << ", "
2482 << TVar( theAngleInRadians ) << ", "
2483 << TVar( theNbOfSteps ) << ", "
2484 << TVar( theTolerance ) << " )";
2489 //=======================================================================
2490 //function : RotationSweepObject
2492 //=======================================================================
2494 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2495 const SMESH::AxisStruct & theAxis,
2496 CORBA::Double theAngleInRadians,
2497 CORBA::Long theNbOfSteps,
2498 CORBA::Double theTolerance)
2499 throw (SALOME::SALOME_Exception)
2501 if ( !myIsPreviewMode ) {
2502 TPythonDump() << this << ".RotationSweepObject( "
2503 << theObject << ", "
2505 << theAngleInRadians << ", "
2506 << theNbOfSteps << ", "
2507 << theTolerance << " )";
2509 prepareIdSource( theObject );
2510 SMESH::long_array_var anElementsId = theObject->GetIDs();
2511 rotationSweep(anElementsId,
2519 //=======================================================================
2520 //function : RotationSweepObject1D
2522 //=======================================================================
2524 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2525 const SMESH::AxisStruct & theAxis,
2526 CORBA::Double theAngleInRadians,
2527 CORBA::Long theNbOfSteps,
2528 CORBA::Double theTolerance)
2529 throw (SALOME::SALOME_Exception)
2531 if ( !myIsPreviewMode ) {
2532 TPythonDump() << this << ".RotationSweepObject1D( "
2533 << theObject << ", "
2535 << TVar( theAngleInRadians ) << ", "
2536 << TVar( theNbOfSteps ) << ", "
2537 << TVar( theTolerance ) << " )";
2539 prepareIdSource( theObject );
2540 SMESH::long_array_var anElementsId = theObject->GetIDs();
2541 rotationSweep(anElementsId,
2550 //=======================================================================
2551 //function : RotationSweepObject2D
2553 //=======================================================================
2555 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2556 const SMESH::AxisStruct & theAxis,
2557 CORBA::Double theAngleInRadians,
2558 CORBA::Long theNbOfSteps,
2559 CORBA::Double theTolerance)
2560 throw (SALOME::SALOME_Exception)
2562 if ( !myIsPreviewMode ) {
2563 TPythonDump() << this << ".RotationSweepObject2D( "
2564 << theObject << ", "
2566 << TVar( theAngleInRadians ) << ", "
2567 << TVar( theNbOfSteps ) << ", "
2568 << TVar( theTolerance ) << " )";
2570 prepareIdSource( theObject );
2571 SMESH::long_array_var anElementsId = theObject->GetIDs();
2572 rotationSweep(anElementsId,
2581 //=======================================================================
2582 //function : RotationSweepObjectMakeGroups
2584 //=======================================================================
2586 SMESH::ListOfGroups*
2587 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2588 const SMESH::AxisStruct& theAxis,
2589 CORBA::Double theAngleInRadians,
2590 CORBA::Long theNbOfSteps,
2591 CORBA::Double theTolerance)
2592 throw (SALOME::SALOME_Exception)
2594 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2596 prepareIdSource( theObject );
2597 SMESH::long_array_var anElementsId = theObject->GetIDs();
2598 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2604 if (!myIsPreviewMode) {
2605 dumpGroupsList(aPythonDump, aGroups);
2606 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2607 << theObject << ", "
2609 << theAngleInRadians << ", "
2610 << theNbOfSteps << ", "
2611 << theTolerance << " )";
2616 //=======================================================================
2617 //function : RotationSweepObject1DMakeGroups
2619 //=======================================================================
2621 SMESH::ListOfGroups*
2622 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2623 const SMESH::AxisStruct& theAxis,
2624 CORBA::Double theAngleInRadians,
2625 CORBA::Long theNbOfSteps,
2626 CORBA::Double theTolerance)
2627 throw (SALOME::SALOME_Exception)
2629 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2631 prepareIdSource( theObject );
2632 SMESH::long_array_var anElementsId = theObject->GetIDs();
2633 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2640 if (!myIsPreviewMode) {
2641 dumpGroupsList(aPythonDump, aGroups);
2642 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2643 << theObject << ", "
2645 << TVar( theAngleInRadians ) << ", "
2646 << TVar( theNbOfSteps ) << ", "
2647 << TVar( theTolerance ) << " )";
2652 //=======================================================================
2653 //function : RotationSweepObject2DMakeGroups
2655 //=======================================================================
2657 SMESH::ListOfGroups*
2658 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2659 const SMESH::AxisStruct& theAxis,
2660 CORBA::Double theAngleInRadians,
2661 CORBA::Long theNbOfSteps,
2662 CORBA::Double theTolerance)
2663 throw (SALOME::SALOME_Exception)
2665 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2667 prepareIdSource( theObject );
2668 SMESH::long_array_var anElementsId = theObject->GetIDs();
2669 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2676 if (!myIsPreviewMode) {
2677 dumpGroupsList(aPythonDump, aGroups);
2678 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2679 << theObject << ", "
2681 << TVar( theAngleInRadians ) << ", "
2682 << TVar( theNbOfSteps ) << ", "
2683 << TVar( theTolerance ) << " )";
2688 namespace MeshEditor_I
2691 * \brief Structure used to pass extrusion parameters to ::SMESH_MeshEditor
2693 struct ExtrusionParams : public ::SMESH_MeshEditor::ExtrusParam
2695 bool myIsExtrusionByNormal;
2697 static int makeFlags( CORBA::Boolean MakeGroups,
2698 CORBA::Boolean ByAverageNormal = false,
2699 CORBA::Boolean UseInputElemsOnly = false,
2700 CORBA::Long Flags = 0,
2701 CORBA::Boolean MakeBoundary = true )
2703 if ( MakeGroups ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS;
2704 if ( ByAverageNormal ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BY_AVG_NORMAL;
2705 if ( UseInputElemsOnly) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY;
2706 if ( MakeBoundary ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BOUNDARY;
2710 ExtrusionParams(const SMESH::DirStruct & theDir,
2711 CORBA::Long theNbOfSteps,
2712 CORBA::Boolean theMakeGroups):
2713 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2717 makeFlags( theMakeGroups )),
2718 myIsExtrusionByNormal( false )
2722 ExtrusionParams(const SMESH::DirStruct & theDir,
2723 CORBA::Long theNbOfSteps,
2724 CORBA::Boolean theMakeGroups,
2725 CORBA::Long theExtrFlags,
2726 CORBA::Double theSewTolerance):
2727 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2731 makeFlags( theMakeGroups, false, false,
2732 theExtrFlags, false ),
2734 myIsExtrusionByNormal( false )
2737 // params for extrusion by normal
2738 ExtrusionParams(CORBA::Double theStepSize,
2739 CORBA::Long theNbOfSteps,
2740 CORBA::Short theDim,
2741 CORBA::Boolean theUseInputElemsOnly,
2742 CORBA::Boolean theByAverageNormal,
2743 CORBA::Boolean theMakeGroups ):
2744 ::SMESH_MeshEditor::ExtrusParam ( theStepSize,
2746 makeFlags( theMakeGroups,
2747 theByAverageNormal, theUseInputElemsOnly ),
2749 myIsExtrusionByNormal( true )
2755 Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS);
2760 //=======================================================================
2761 //function : extrusionSweep
2763 //=======================================================================
2765 SMESH::ListOfGroups*
2766 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2767 MeshEditor_I::ExtrusionParams& theParams,
2768 const SMDSAbs_ElementType theElementType)
2769 throw (SALOME::SALOME_Exception)
2774 TIDSortedElemSet elements, copyElements;
2775 arrayToSet( theIDsOfElements, getMeshDS(), elements, theElementType );
2777 TIDSortedElemSet* workElements = & elements;
2779 if ( myIsPreviewMode )
2781 SMDSAbs_ElementType previewType = SMDSAbs_Face;
2782 if (theElementType == SMDSAbs_Node)
2783 previewType = SMDSAbs_Edge;
2785 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2786 getPreviewMesh( previewType )->Copy( elements, copyElements, select, avoid );
2787 workElements = & copyElements;
2788 theParams.SetNoGroups();
2790 if ( theParams.myIsExtrusionByNormal && !theParams.ToUseInpElemsOnly() )
2792 TIDSortedElemSet elemsAround, elemsAroundCopy;
2793 getElementsAround( elements, getMeshDS(), elemsAround );
2794 getPreviewMesh( previewType )->Copy( elemsAround, elemsAroundCopy, select, avoid );
2798 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2799 ::SMESH_MeshEditor::PGroupIDs groupIds =
2800 getEditor().ExtrusionSweep (*workElements, theParams, aHystory );
2802 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2804 return theParams.ToMakeGroups() ? getGroups(groupIds.get()) : 0;
2806 SMESH_CATCH( SMESH::throwCorbaException );
2810 //=======================================================================
2811 //function : ExtrusionSweep
2813 //=======================================================================
2815 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2816 const SMESH::DirStruct & theStepVector,
2817 CORBA::Long theNbOfSteps)
2818 throw (SALOME::SALOME_Exception)
2820 ExtrusionParams params( theStepVector, theNbOfSteps, false );
2821 extrusionSweep( theIDsOfElements, params );
2822 if (!myIsPreviewMode) {
2823 TPythonDump() << this << ".ExtrusionSweep( "
2824 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2828 //=======================================================================
2829 //function : ExtrusionSweep0D
2831 //=======================================================================
2833 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2834 const SMESH::DirStruct & theStepVector,
2835 CORBA::Long theNbOfSteps)
2836 throw (SALOME::SALOME_Exception)
2838 ExtrusionParams params( theStepVector, theNbOfSteps, false );
2839 extrusionSweep( theIDsOfElements, params, SMDSAbs_Node );
2840 if (!myIsPreviewMode) {
2841 TPythonDump() << this << ".ExtrusionSweep0D( "
2842 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2846 //=======================================================================
2847 //function : ExtrusionSweepObject
2849 //=======================================================================
2851 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2852 const SMESH::DirStruct & theStepVector,
2853 CORBA::Long theNbOfSteps)
2854 throw (SALOME::SALOME_Exception)
2856 prepareIdSource( theObject );
2857 SMESH::long_array_var anElementsId = theObject->GetIDs();
2858 ExtrusionParams params( theStepVector, theNbOfSteps, false );
2859 extrusionSweep( anElementsId, params );
2860 if (!myIsPreviewMode) {
2861 TPythonDump() << this << ".ExtrusionSweepObject( "
2862 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2866 //=======================================================================
2867 //function : ExtrusionSweepObject0D
2869 //=======================================================================
2871 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2872 const SMESH::DirStruct & theStepVector,
2873 CORBA::Long theNbOfSteps)
2874 throw (SALOME::SALOME_Exception)
2876 prepareIdSource( theObject );
2877 SMESH::long_array_var anElementsId = theObject->GetIDs();
2878 if ( anElementsId->length() == 0 )
2879 if ( SMESH_Mesh_i* mesh = SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
2880 anElementsId = mesh->GetNodesId();
2882 ExtrusionParams params( theStepVector, theNbOfSteps, false );
2883 extrusionSweep( anElementsId, params, SMDSAbs_Node );
2884 if ( !myIsPreviewMode ) {
2885 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2886 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2890 //=======================================================================
2891 //function : ExtrusionSweepObject1D
2893 //=======================================================================
2895 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2896 const SMESH::DirStruct & theStepVector,
2897 CORBA::Long theNbOfSteps)
2898 throw (SALOME::SALOME_Exception)
2900 prepareIdSource( theObject );
2901 SMESH::long_array_var anElementsId = theObject->GetIDs();
2902 ExtrusionParams params( theStepVector, theNbOfSteps, false );
2903 extrusionSweep( anElementsId, params, SMDSAbs_Edge );
2904 if ( !myIsPreviewMode ) {
2905 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2906 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2910 //=======================================================================
2911 //function : ExtrusionSweepObject2D
2913 //=======================================================================
2915 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2916 const SMESH::DirStruct & theStepVector,
2917 CORBA::Long theNbOfSteps)
2918 throw (SALOME::SALOME_Exception)
2920 prepareIdSource( theObject );
2921 SMESH::long_array_var anElementsId = theObject->GetIDs();
2922 ExtrusionParams params( theStepVector, theNbOfSteps, false );
2923 extrusionSweep( anElementsId, params, SMDSAbs_Face );
2924 if ( !myIsPreviewMode ) {
2925 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2926 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2930 //=======================================================================
2931 //function : ExtrusionSweepMakeGroups
2933 //=======================================================================
2935 SMESH::ListOfGroups*
2936 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2937 const SMESH::DirStruct& theStepVector,
2938 CORBA::Long theNbOfSteps)
2939 throw (SALOME::SALOME_Exception)
2941 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2943 ExtrusionParams params( theStepVector, theNbOfSteps, true );
2944 SMESH::ListOfGroups* aGroups = extrusionSweep( theIDsOfElements, params );
2946 if (!myIsPreviewMode) {
2947 dumpGroupsList(aPythonDump, aGroups);
2948 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2949 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2954 //=======================================================================
2955 //function : ExtrusionSweepMakeGroups0D
2957 //=======================================================================
2959 SMESH::ListOfGroups*
2960 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2961 const SMESH::DirStruct& theStepVector,
2962 CORBA::Long theNbOfSteps)
2963 throw (SALOME::SALOME_Exception)
2965 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2967 ExtrusionParams params( theStepVector, theNbOfSteps, true );
2968 SMESH::ListOfGroups* aGroups = extrusionSweep( theIDsOfElements, params, SMDSAbs_Node );
2970 if (!myIsPreviewMode) {
2971 dumpGroupsList(aPythonDump, aGroups);
2972 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2973 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2978 //=======================================================================
2979 //function : ExtrusionSweepObjectMakeGroups
2981 //=======================================================================
2983 SMESH::ListOfGroups*
2984 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2985 const SMESH::DirStruct& theStepVector,
2986 CORBA::Long theNbOfSteps)
2987 throw (SALOME::SALOME_Exception)
2989 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2991 prepareIdSource( theObject );
2992 SMESH::long_array_var anElementsId = theObject->GetIDs();
2993 ExtrusionParams params( theStepVector, theNbOfSteps, true );
2994 SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params );
2996 if (!myIsPreviewMode) {
2997 dumpGroupsList(aPythonDump, aGroups);
2998 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2999 << ", " << theStepVector << ", " << theNbOfSteps << " )";
3004 //=======================================================================
3005 //function : ExtrusionSweepObject0DMakeGroups
3007 //=======================================================================
3009 SMESH::ListOfGroups*
3010 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3011 const SMESH::DirStruct& theStepVector,
3012 CORBA::Long theNbOfSteps)
3013 throw (SALOME::SALOME_Exception)
3015 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3017 prepareIdSource( theObject );
3018 SMESH::long_array_var anElementsId = theObject->GetIDs();
3019 ExtrusionParams params( theStepVector, theNbOfSteps, true );
3020 SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params, SMDSAbs_Node );
3022 if (!myIsPreviewMode) {
3023 dumpGroupsList(aPythonDump, aGroups);
3024 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
3025 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
3030 //=======================================================================
3031 //function : ExtrusionSweepObject1DMakeGroups
3033 //=======================================================================
3035 SMESH::ListOfGroups*
3036 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3037 const SMESH::DirStruct& theStepVector,
3038 CORBA::Long theNbOfSteps)
3039 throw (SALOME::SALOME_Exception)
3041 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3043 prepareIdSource( theObject );
3044 SMESH::long_array_var anElementsId = theObject->GetIDs();
3045 ExtrusionParams params( theStepVector, theNbOfSteps, true );
3046 SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params, SMDSAbs_Edge );
3048 if (!myIsPreviewMode) {
3049 dumpGroupsList(aPythonDump, aGroups);
3050 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
3051 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
3056 //=======================================================================
3057 //function : ExtrusionSweepObject2DMakeGroups
3059 //=======================================================================
3061 SMESH::ListOfGroups*
3062 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3063 const SMESH::DirStruct& theStepVector,
3064 CORBA::Long theNbOfSteps)
3065 throw (SALOME::SALOME_Exception)
3067 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3069 prepareIdSource( theObject );
3070 SMESH::long_array_var anElementsId = theObject->GetIDs();
3071 ExtrusionParams params( theStepVector, theNbOfSteps, true );
3072 SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params, SMDSAbs_Face );
3074 if (!myIsPreviewMode) {
3075 dumpGroupsList(aPythonDump, aGroups);
3076 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
3077 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
3082 //=======================================================================
3083 //function : ExtrusionByNormal
3085 //=======================================================================
3087 SMESH::ListOfGroups*
3088 SMESH_MeshEditor_i::ExtrusionByNormal(SMESH::SMESH_IDSource_ptr object,
3089 CORBA::Double stepSize,
3090 CORBA::Long nbOfSteps,
3091 CORBA::Boolean byAverageNormal,
3092 CORBA::Boolean useInputElemsOnly,
3093 CORBA::Boolean makeGroups,
3095 throw (SALOME::SALOME_Exception)
3097 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3099 ExtrusionParams params( stepSize, nbOfSteps, dim,
3100 byAverageNormal, useInputElemsOnly, makeGroups );
3102 SMDSAbs_ElementType elemType = ( dim == 1 ? SMDSAbs_Edge : SMDSAbs_Face );
3103 if ( !SMESH::DownCast<SMESH_Mesh_i*>( object ))
3105 SMESH::array_of_ElementType_var elemTypes = object->GetTypes();
3106 if (( elemTypes->length() == 1 ) &&
3107 ( elemTypes[0] == SMESH::EDGE || elemTypes[0] == SMESH::FACE ))
3108 elemType = ( SMDSAbs_ElementType ) elemTypes[0];
3110 prepareIdSource( object );
3111 SMESH::long_array_var anElementsId = object->GetIDs();
3112 SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params, elemType );
3114 if (!myIsPreviewMode) {
3115 dumpGroupsList(aPythonDump, aGroups);
3116 aPythonDump << this << ".ExtrusionByNormal( " << object
3117 << ", " << TVar( stepSize )
3118 << ", " << TVar( nbOfSteps )
3119 << ", " << byAverageNormal
3120 << ", " << makeGroups
3127 //=======================================================================
3128 //function : AdvancedExtrusion
3130 //=======================================================================
3132 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
3133 const SMESH::DirStruct & theStepVector,
3134 CORBA::Long theNbOfSteps,
3135 CORBA::Long theExtrFlags,
3136 CORBA::Double theSewTolerance)
3137 throw (SALOME::SALOME_Exception)
3139 ExtrusionParams params( theStepVector, theNbOfSteps, false, theExtrFlags, theSewTolerance);
3140 extrusionSweep( theIDsOfElements, params );
3142 if ( !myIsPreviewMode ) {
3143 TPythonDump() << "stepVector = " << theStepVector;
3144 TPythonDump() << this << ".AdvancedExtrusion("
3147 << theNbOfSteps << ","
3148 << theExtrFlags << ", "
3149 << theSewTolerance << " )";
3153 //=======================================================================
3154 //function : AdvancedExtrusionMakeGroups
3156 //=======================================================================
3157 SMESH::ListOfGroups*
3158 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
3159 const SMESH::DirStruct& theStepVector,
3160 CORBA::Long theNbOfSteps,
3161 CORBA::Long theExtrFlags,
3162 CORBA::Double theSewTolerance)
3163 throw (SALOME::SALOME_Exception)
3165 if (!myIsPreviewMode) {
3166 TPythonDump() << "stepVector = " << theStepVector;
3168 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3170 ExtrusionParams params( theStepVector, theNbOfSteps, true, theExtrFlags, theSewTolerance);
3171 SMESH::ListOfGroups * aGroups = extrusionSweep( theIDsOfElements, params );
3173 if (!myIsPreviewMode) {
3174 dumpGroupsList(aPythonDump, aGroups);
3175 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
3178 << theNbOfSteps << ","
3179 << theExtrFlags << ", "
3180 << theSewTolerance << " )";
3186 //================================================================================
3188 * \brief Convert extrusion error to IDL enum
3190 //================================================================================
3192 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
3194 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
3198 RETCASE( EXTR_NO_ELEMENTS );
3199 RETCASE( EXTR_PATH_NOT_EDGE );
3200 RETCASE( EXTR_BAD_PATH_SHAPE );
3201 RETCASE( EXTR_BAD_STARTING_NODE );
3202 RETCASE( EXTR_BAD_ANGLES_NUMBER );
3203 RETCASE( EXTR_CANT_GET_TANGENT );
3205 return SMESH::SMESH_MeshEditor::EXTR_OK;
3209 //=======================================================================
3210 //function : extrusionAlongPath
3212 //=======================================================================
3213 SMESH::ListOfGroups*
3214 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3215 SMESH::SMESH_Mesh_ptr thePathMesh,
3216 GEOM::GEOM_Object_ptr thePathShape,
3217 CORBA::Long theNodeStart,
3218 CORBA::Boolean theHasAngles,
3219 const SMESH::double_array & theAngles,
3220 CORBA::Boolean theHasRefPoint,
3221 const SMESH::PointStruct & theRefPoint,
3222 const bool theMakeGroups,
3223 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
3224 const SMDSAbs_ElementType theElementType)
3225 throw (SALOME::SALOME_Exception)
3228 MESSAGE("extrusionAlongPath");
3231 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
3232 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3235 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3237 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3238 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3240 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
3241 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3245 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
3247 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3251 TIDSortedElemSet elements;
3252 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
3254 list<double> angles;
3255 for (int i = 0; i < theAngles.length(); i++) {
3256 angles.push_back( theAngles[i] );
3259 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
3261 int nbOldGroups = myMesh->NbGroup();
3263 ::SMESH_MeshEditor::Extrusion_Error error =
3264 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
3265 theHasAngles, angles, false,
3266 theHasRefPoint, refPnt, theMakeGroups );
3268 declareMeshModified( /*isReComputeSafe=*/true );
3269 theError = convExtrError( error );
3271 if ( theMakeGroups ) {
3272 list<int> groupIDs = myMesh->GetGroupIds();
3273 list<int>::iterator newBegin = groupIDs.begin();
3274 std::advance( newBegin, nbOldGroups ); // skip old groups
3275 groupIDs.erase( groupIDs.begin(), newBegin );
3276 return getGroups( & groupIDs );
3280 SMESH_CATCH( SMESH::throwCorbaException );
3284 //=======================================================================
3285 //function : extrusionAlongPathX
3287 //=======================================================================
3289 SMESH::ListOfGroups*
3290 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
3291 SMESH::SMESH_IDSource_ptr Path,
3292 CORBA::Long NodeStart,
3293 CORBA::Boolean HasAngles,
3294 const SMESH::double_array& Angles,
3295 CORBA::Boolean LinearVariation,
3296 CORBA::Boolean HasRefPoint,
3297 const SMESH::PointStruct& RefPoint,
3299 const SMDSAbs_ElementType ElementType,
3300 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
3301 throw (SALOME::SALOME_Exception)
3304 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
3308 list<double> angles;
3309 for (int i = 0; i < Angles.length(); i++) {
3310 angles.push_back( Angles[i] );
3312 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
3313 int nbOldGroups = myMesh->NbGroup();
3315 if ( Path->_is_nil() ) {
3316 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3320 TIDSortedElemSet elements, copyElements;
3321 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
3323 TIDSortedElemSet* workElements = &elements;
3325 if ( myIsPreviewMode )
3327 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
3328 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
3329 workElements = & copyElements;
3333 ::SMESH_MeshEditor::Extrusion_Error error;
3335 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
3338 SMDS_MeshNode* aNodeStart =
3339 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3340 if ( !aNodeStart ) {
3341 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3344 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
3345 HasAngles, angles, LinearVariation,
3346 HasRefPoint, refPnt, MakeGroups );
3347 declareMeshModified( /*isReComputeSafe=*/true );
3349 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
3352 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
3353 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
3354 SMDS_MeshNode* aNodeStart =
3355 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3356 if ( !aNodeStart ) {
3357 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3360 SMESH_subMesh* aSubMesh =
3361 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
3362 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
3363 HasAngles, angles, LinearVariation,
3364 HasRefPoint, refPnt, MakeGroups );
3365 declareMeshModified( /*isReComputeSafe=*/true );
3367 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
3369 // path as group of 1D elements
3375 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3379 Error = convExtrError( error );
3382 list<int> groupIDs = myMesh->GetGroupIds();
3383 list<int>::iterator newBegin = groupIDs.begin();
3384 std::advance( newBegin, nbOldGroups ); // skip old groups
3385 groupIDs.erase( groupIDs.begin(), newBegin );
3386 return getGroups( & groupIDs );
3390 SMESH_CATCH( SMESH::throwCorbaException );
3394 //=======================================================================
3395 //function : ExtrusionAlongPath
3397 //=======================================================================
3399 SMESH::SMESH_MeshEditor::Extrusion_Error
3400 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3401 SMESH::SMESH_Mesh_ptr thePathMesh,
3402 GEOM::GEOM_Object_ptr thePathShape,
3403 CORBA::Long theNodeStart,
3404 CORBA::Boolean theHasAngles,
3405 const SMESH::double_array & theAngles,
3406 CORBA::Boolean theHasRefPoint,
3407 const SMESH::PointStruct & theRefPoint)
3408 throw (SALOME::SALOME_Exception)
3410 MESSAGE("ExtrusionAlongPath");
3411 if ( !myIsPreviewMode ) {
3412 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
3413 << theIDsOfElements << ", "
3414 << thePathMesh << ", "
3415 << thePathShape << ", "
3416 << theNodeStart << ", "
3417 << theHasAngles << ", "
3418 << theAngles << ", "
3419 << theHasRefPoint << ", "
3420 << "SMESH.PointStruct( "
3421 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3422 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3423 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3425 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3426 extrusionAlongPath( theIDsOfElements,
3439 //=======================================================================
3440 //function : ExtrusionAlongPathObject
3442 //=======================================================================
3444 SMESH::SMESH_MeshEditor::Extrusion_Error
3445 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
3446 SMESH::SMESH_Mesh_ptr thePathMesh,
3447 GEOM::GEOM_Object_ptr thePathShape,
3448 CORBA::Long theNodeStart,
3449 CORBA::Boolean theHasAngles,
3450 const SMESH::double_array & theAngles,
3451 CORBA::Boolean theHasRefPoint,
3452 const SMESH::PointStruct & theRefPoint)
3453 throw (SALOME::SALOME_Exception)
3455 if ( !myIsPreviewMode ) {
3456 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
3457 << theObject << ", "
3458 << thePathMesh << ", "
3459 << thePathShape << ", "
3460 << theNodeStart << ", "
3461 << theHasAngles << ", "
3462 << theAngles << ", "
3463 << theHasRefPoint << ", "
3464 << "SMESH.PointStruct( "
3465 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3466 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3467 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3469 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3470 prepareIdSource( theObject );
3471 SMESH::long_array_var anElementsId = theObject->GetIDs();
3472 extrusionAlongPath( anElementsId,
3485 //=======================================================================
3486 //function : ExtrusionAlongPathObject1D
3488 //=======================================================================
3490 SMESH::SMESH_MeshEditor::Extrusion_Error
3491 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
3492 SMESH::SMESH_Mesh_ptr thePathMesh,
3493 GEOM::GEOM_Object_ptr thePathShape,
3494 CORBA::Long theNodeStart,
3495 CORBA::Boolean theHasAngles,
3496 const SMESH::double_array & theAngles,
3497 CORBA::Boolean theHasRefPoint,
3498 const SMESH::PointStruct & theRefPoint)
3499 throw (SALOME::SALOME_Exception)
3501 if ( !myIsPreviewMode ) {
3502 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
3503 << theObject << ", "
3504 << thePathMesh << ", "
3505 << thePathShape << ", "
3506 << theNodeStart << ", "
3507 << theHasAngles << ", "
3508 << theAngles << ", "
3509 << theHasRefPoint << ", "
3510 << "SMESH.PointStruct( "
3511 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3512 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3513 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3515 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3516 prepareIdSource( theObject );
3517 SMESH::long_array_var anElementsId = theObject->GetIDs();
3518 extrusionAlongPath( anElementsId,
3532 //=======================================================================
3533 //function : ExtrusionAlongPathObject2D
3535 //=======================================================================
3537 SMESH::SMESH_MeshEditor::Extrusion_Error
3538 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3539 SMESH::SMESH_Mesh_ptr thePathMesh,
3540 GEOM::GEOM_Object_ptr thePathShape,
3541 CORBA::Long theNodeStart,
3542 CORBA::Boolean theHasAngles,
3543 const SMESH::double_array & theAngles,
3544 CORBA::Boolean theHasRefPoint,
3545 const SMESH::PointStruct & theRefPoint)
3546 throw (SALOME::SALOME_Exception)
3548 if ( !myIsPreviewMode ) {
3549 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3550 << theObject << ", "
3551 << thePathMesh << ", "
3552 << thePathShape << ", "
3553 << theNodeStart << ", "
3554 << theHasAngles << ", "
3555 << theAngles << ", "
3556 << theHasRefPoint << ", "
3557 << "SMESH.PointStruct( "
3558 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3559 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3560 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3562 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3563 prepareIdSource( theObject );
3564 SMESH::long_array_var anElementsId = theObject->GetIDs();
3565 extrusionAlongPath( anElementsId,
3580 //=======================================================================
3581 //function : ExtrusionAlongPathMakeGroups
3583 //=======================================================================
3585 SMESH::ListOfGroups*
3586 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3587 SMESH::SMESH_Mesh_ptr thePathMesh,
3588 GEOM::GEOM_Object_ptr thePathShape,
3589 CORBA::Long theNodeStart,
3590 CORBA::Boolean theHasAngles,
3591 const SMESH::double_array& theAngles,
3592 CORBA::Boolean theHasRefPoint,
3593 const SMESH::PointStruct& theRefPoint,
3594 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3595 throw (SALOME::SALOME_Exception)
3597 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3599 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3609 if (!myIsPreviewMode) {
3610 bool isDumpGroups = aGroups && aGroups->length() > 0;
3612 aPythonDump << "(" << aGroups << ", error)";
3614 aPythonDump <<"error";
3616 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3617 << theIDsOfElements << ", "
3618 << thePathMesh << ", "
3619 << thePathShape << ", "
3620 << theNodeStart << ", "
3621 << theHasAngles << ", "
3622 << theAngles << ", "
3623 << theHasRefPoint << ", "
3624 << "SMESH.PointStruct( "
3625 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3626 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3627 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3632 //=======================================================================
3633 //function : ExtrusionAlongPathObjectMakeGroups
3635 //=======================================================================
3637 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3638 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3639 SMESH::SMESH_Mesh_ptr thePathMesh,
3640 GEOM::GEOM_Object_ptr thePathShape,
3641 CORBA::Long theNodeStart,
3642 CORBA::Boolean theHasAngles,
3643 const SMESH::double_array& theAngles,
3644 CORBA::Boolean theHasRefPoint,
3645 const SMESH::PointStruct& theRefPoint,
3646 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3647 throw (SALOME::SALOME_Exception)
3649 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3651 prepareIdSource( theObject );
3652 SMESH::long_array_var anElementsId = theObject->GetIDs();
3653 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3664 if (!myIsPreviewMode) {
3665 bool isDumpGroups = aGroups && aGroups->length() > 0;
3667 aPythonDump << "(" << aGroups << ", error)";
3669 aPythonDump <<"error";
3671 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3672 << theObject << ", "
3673 << thePathMesh << ", "
3674 << thePathShape << ", "
3675 << theNodeStart << ", "
3676 << theHasAngles << ", "
3677 << theAngles << ", "
3678 << theHasRefPoint << ", "
3679 << "SMESH.PointStruct( "
3680 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3681 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3682 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3687 //=======================================================================
3688 //function : ExtrusionAlongPathObject1DMakeGroups
3690 //=======================================================================
3692 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3693 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3694 SMESH::SMESH_Mesh_ptr thePathMesh,
3695 GEOM::GEOM_Object_ptr thePathShape,
3696 CORBA::Long theNodeStart,
3697 CORBA::Boolean theHasAngles,
3698 const SMESH::double_array& theAngles,
3699 CORBA::Boolean theHasRefPoint,
3700 const SMESH::PointStruct& theRefPoint,
3701 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3702 throw (SALOME::SALOME_Exception)
3704 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3706 prepareIdSource( theObject );
3707 SMESH::long_array_var anElementsId = theObject->GetIDs();
3708 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3720 if (!myIsPreviewMode) {
3721 bool isDumpGroups = aGroups && aGroups->length() > 0;
3723 aPythonDump << "(" << aGroups << ", error)";
3725 aPythonDump << "error";
3727 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3728 << theObject << ", "
3729 << thePathMesh << ", "
3730 << thePathShape << ", "
3731 << theNodeStart << ", "
3732 << theHasAngles << ", "
3733 << theAngles << ", "
3734 << theHasRefPoint << ", "
3735 << "SMESH.PointStruct( "
3736 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3737 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3738 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3743 //=======================================================================
3744 //function : ExtrusionAlongPathObject2DMakeGroups
3746 //=======================================================================
3748 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3749 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3750 SMESH::SMESH_Mesh_ptr thePathMesh,
3751 GEOM::GEOM_Object_ptr thePathShape,
3752 CORBA::Long theNodeStart,
3753 CORBA::Boolean theHasAngles,
3754 const SMESH::double_array& theAngles,
3755 CORBA::Boolean theHasRefPoint,
3756 const SMESH::PointStruct& theRefPoint,
3757 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3758 throw (SALOME::SALOME_Exception)
3760 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3762 prepareIdSource( theObject );
3763 SMESH::long_array_var anElementsId = theObject->GetIDs();
3764 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3776 if (!myIsPreviewMode) {
3777 bool isDumpGroups = aGroups && aGroups->length() > 0;
3779 aPythonDump << "(" << aGroups << ", error)";
3781 aPythonDump << "error";
3783 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3784 << theObject << ", "
3785 << thePathMesh << ", "
3786 << thePathShape << ", "
3787 << theNodeStart << ", "
3788 << theHasAngles << ", "
3789 << theAngles << ", "
3790 << theHasRefPoint << ", "
3791 << "SMESH.PointStruct( "
3792 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3793 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3794 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3799 //=======================================================================
3800 //function : ExtrusionAlongPathObjX
3802 //=======================================================================
3804 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3805 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3806 SMESH::SMESH_IDSource_ptr Path,
3807 CORBA::Long NodeStart,
3808 CORBA::Boolean HasAngles,
3809 const SMESH::double_array& Angles,
3810 CORBA::Boolean LinearVariation,
3811 CORBA::Boolean HasRefPoint,
3812 const SMESH::PointStruct& RefPoint,
3813 CORBA::Boolean MakeGroups,
3814 SMESH::ElementType ElemType,
3815 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3816 throw (SALOME::SALOME_Exception)
3818 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3820 prepareIdSource( Object );
3821 SMESH::long_array_var anElementsId = Object->GetIDs();
3822 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3831 (SMDSAbs_ElementType)ElemType,
3834 if (!myIsPreviewMode) {
3835 bool isDumpGroups = aGroups && aGroups->length() > 0;
3837 aPythonDump << "(" << *aGroups << ", error)";
3839 aPythonDump << "error";
3841 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3844 << NodeStart << ", "
3845 << HasAngles << ", "
3846 << TVar( Angles ) << ", "
3847 << LinearVariation << ", "
3848 << HasRefPoint << ", "
3849 << "SMESH.PointStruct( "
3850 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3851 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3852 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3853 << MakeGroups << ", "
3854 << ElemType << " )";
3859 //=======================================================================
3860 //function : ExtrusionAlongPathX
3862 //=======================================================================
3864 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3865 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3866 SMESH::SMESH_IDSource_ptr Path,
3867 CORBA::Long NodeStart,
3868 CORBA::Boolean HasAngles,
3869 const SMESH::double_array& Angles,
3870 CORBA::Boolean LinearVariation,
3871 CORBA::Boolean HasRefPoint,
3872 const SMESH::PointStruct& RefPoint,
3873 CORBA::Boolean MakeGroups,
3874 SMESH::ElementType ElemType,
3875 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3876 throw (SALOME::SALOME_Exception)
3878 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3880 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3889 (SMDSAbs_ElementType)ElemType,
3892 if (!myIsPreviewMode) {
3893 bool isDumpGroups = aGroups && aGroups->length() > 0;
3895 aPythonDump << "(" << *aGroups << ", error)";
3897 aPythonDump <<"error";
3899 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3900 << IDsOfElements << ", "
3902 << NodeStart << ", "
3903 << HasAngles << ", "
3904 << TVar( Angles ) << ", "
3905 << LinearVariation << ", "
3906 << HasRefPoint << ", "
3907 << "SMESH.PointStruct( "
3908 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3909 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3910 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3911 << MakeGroups << ", "
3912 << ElemType << " )";
3917 //================================================================================
3919 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3920 * of given angles along path steps
3921 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3922 * which proceeds the extrusion
3923 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3924 * is used to define the sub-mesh for the path
3926 //================================================================================
3928 SMESH::double_array*
3929 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3930 GEOM::GEOM_Object_ptr thePathShape,
3931 const SMESH::double_array & theAngles)
3933 SMESH::double_array_var aResult = new SMESH::double_array();
3934 int nbAngles = theAngles.length();
3935 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3937 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3938 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3939 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3940 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3941 return aResult._retn();
3942 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3943 if ( nbSteps == nbAngles )
3945 aResult.inout() = theAngles;
3949 aResult->length( nbSteps );
3950 double rAn2St = double( nbAngles ) / double( nbSteps );
3951 double angPrev = 0, angle;
3952 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3954 double angCur = rAn2St * ( iSt+1 );
3955 double angCurFloor = floor( angCur );
3956 double angPrevFloor = floor( angPrev );
3957 if ( angPrevFloor == angCurFloor )
3958 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3961 int iP = int( angPrevFloor );
3962 double angPrevCeil = ceil(angPrev);
3963 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3965 int iC = int( angCurFloor );
3966 if ( iC < nbAngles )
3967 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3969 iP = int( angPrevCeil );
3971 angle += theAngles[ iC ];
3973 aResult[ iSt ] = angle;
3978 // Update Python script
3979 TPythonDump() << "rotAngles = " << theAngles;
3980 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3981 << thePathMesh << ", "
3982 << thePathShape << ", "
3985 return aResult._retn();
3988 //=======================================================================
3991 //=======================================================================
3993 SMESH::ListOfGroups*
3994 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3995 const SMESH::AxisStruct & theAxis,
3996 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3997 CORBA::Boolean theCopy,
3999 ::SMESH_Mesh* theTargetMesh)
4000 throw (SALOME::SALOME_Exception)
4005 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
4006 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
4008 if ( theTargetMesh )
4012 switch ( theMirrorType ) {
4013 case SMESH::SMESH_MeshEditor::POINT:
4014 aTrsf.SetMirror( P );
4016 case SMESH::SMESH_MeshEditor::AXIS:
4017 aTrsf.SetMirror( gp_Ax1( P, V ));
4020 aTrsf.SetMirror( gp_Ax2( P, V ));
4023 TIDSortedElemSet copyElements;
4024 TIDSortedElemSet* workElements = & theElements;
4026 if ( myIsPreviewMode )
4028 TPreviewMesh * tmpMesh = getPreviewMesh();
4029 tmpMesh->Copy( theElements, copyElements);
4030 if ( !theCopy && !theTargetMesh )
4032 TIDSortedElemSet elemsAround, elemsAroundCopy;
4033 getElementsAround( theElements, getMeshDS(), elemsAround );
4034 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4036 workElements = & copyElements;
4037 theMakeGroups = false;
4040 ::SMESH_MeshEditor::PGroupIDs groupIds =
4041 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4043 if ( theCopy && !myIsPreviewMode)
4045 if ( theTargetMesh )
4047 theTargetMesh->GetMeshDS()->Modified();
4051 declareMeshModified( /*isReComputeSafe=*/false );
4054 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4056 SMESH_CATCH( SMESH::throwCorbaException );
4060 //=======================================================================
4063 //=======================================================================
4065 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
4066 const SMESH::AxisStruct & theAxis,
4067 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4068 CORBA::Boolean theCopy)
4069 throw (SALOME::SALOME_Exception)
4071 if ( !myIsPreviewMode ) {
4072 TPythonDump() << this << ".Mirror( "
4073 << theIDsOfElements << ", "
4075 << mirrorTypeName(theMirrorType) << ", "
4078 if ( theIDsOfElements.length() > 0 )
4080 TIDSortedElemSet elements;
4081 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4082 mirror(elements, theAxis, theMirrorType, theCopy, false);
4087 //=======================================================================
4088 //function : MirrorObject
4090 //=======================================================================
4092 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
4093 const SMESH::AxisStruct & theAxis,
4094 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4095 CORBA::Boolean theCopy)
4096 throw (SALOME::SALOME_Exception)
4098 if ( !myIsPreviewMode ) {
4099 TPythonDump() << this << ".MirrorObject( "
4100 << theObject << ", "
4102 << mirrorTypeName(theMirrorType) << ", "
4105 TIDSortedElemSet elements;
4107 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4109 prepareIdSource( theObject );
4110 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4111 mirror(elements, theAxis, theMirrorType, theCopy, false);
4114 //=======================================================================
4115 //function : MirrorMakeGroups
4117 //=======================================================================
4119 SMESH::ListOfGroups*
4120 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
4121 const SMESH::AxisStruct& theMirror,
4122 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
4123 throw (SALOME::SALOME_Exception)
4125 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4127 SMESH::ListOfGroups * aGroups = 0;
4128 if ( theIDsOfElements.length() > 0 )
4130 TIDSortedElemSet elements;
4131 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4132 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
4134 if (!myIsPreviewMode) {
4135 dumpGroupsList(aPythonDump, aGroups);
4136 aPythonDump << this << ".MirrorMakeGroups( "
4137 << theIDsOfElements << ", "
4138 << theMirror << ", "
4139 << mirrorTypeName(theMirrorType) << " )";
4144 //=======================================================================
4145 //function : MirrorObjectMakeGroups
4147 //=======================================================================
4149 SMESH::ListOfGroups*
4150 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4151 const SMESH::AxisStruct& theMirror,
4152 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
4153 throw (SALOME::SALOME_Exception)
4155 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4157 SMESH::ListOfGroups * aGroups = 0;
4158 TIDSortedElemSet elements;
4159 prepareIdSource( theObject );
4160 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4161 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
4163 if (!myIsPreviewMode)
4165 dumpGroupsList(aPythonDump,aGroups);
4166 aPythonDump << this << ".MirrorObjectMakeGroups( "
4167 << theObject << ", "
4168 << theMirror << ", "
4169 << mirrorTypeName(theMirrorType) << " )";
4174 //=======================================================================
4175 //function : MirrorMakeMesh
4177 //=======================================================================
4179 SMESH::SMESH_Mesh_ptr
4180 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
4181 const SMESH::AxisStruct& theMirror,
4182 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4183 CORBA::Boolean theCopyGroups,
4184 const char* theMeshName)
4185 throw (SALOME::SALOME_Exception)
4187 SMESH_Mesh_i* mesh_i;
4188 SMESH::SMESH_Mesh_var mesh;
4189 { // open new scope to dump "MakeMesh" command
4190 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4192 TPythonDump pydump; // to prevent dump at mesh creation
4194 mesh = makeMesh( theMeshName );
4195 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4196 if (mesh_i && theIDsOfElements.length() > 0 )
4198 TIDSortedElemSet elements;
4199 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4200 mirror(elements, theMirror, theMirrorType,
4201 false, theCopyGroups, & mesh_i->GetImpl());
4202 mesh_i->CreateGroupServants();
4205 if (!myIsPreviewMode) {
4206 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
4207 << theIDsOfElements << ", "
4208 << theMirror << ", "
4209 << mirrorTypeName(theMirrorType) << ", "
4210 << theCopyGroups << ", '"
4211 << theMeshName << "' )";
4216 if (!myIsPreviewMode && mesh_i)
4217 mesh_i->GetGroups();
4219 return mesh._retn();
4222 //=======================================================================
4223 //function : MirrorObjectMakeMesh
4225 //=======================================================================
4227 SMESH::SMESH_Mesh_ptr
4228 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4229 const SMESH::AxisStruct& theMirror,
4230 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4231 CORBA::Boolean theCopyGroups,
4232 const char* theMeshName)
4233 throw (SALOME::SALOME_Exception)
4235 SMESH_Mesh_i* mesh_i;
4236 SMESH::SMESH_Mesh_var mesh;
4237 { // open new scope to dump "MakeMesh" command
4238 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4240 TPythonDump pydump; // to prevent dump at mesh creation
4242 mesh = makeMesh( theMeshName );
4243 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4244 TIDSortedElemSet elements;
4245 prepareIdSource( theObject );
4247 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4249 mirror(elements, theMirror, theMirrorType,
4250 false, theCopyGroups, & mesh_i->GetImpl());
4251 mesh_i->CreateGroupServants();
4253 if (!myIsPreviewMode) {
4254 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
4255 << theObject << ", "
4256 << theMirror << ", "
4257 << mirrorTypeName(theMirrorType) << ", "
4258 << theCopyGroups << ", '"
4259 << theMeshName << "' )";
4264 if (!myIsPreviewMode && mesh_i)
4265 mesh_i->GetGroups();
4267 return mesh._retn();
4270 //=======================================================================
4271 //function : translate
4273 //=======================================================================
4275 SMESH::ListOfGroups*
4276 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
4277 const SMESH::DirStruct & theVector,
4278 CORBA::Boolean theCopy,
4280 ::SMESH_Mesh* theTargetMesh)
4281 throw (SALOME::SALOME_Exception)
4286 if ( theTargetMesh )
4290 const SMESH::PointStruct * P = &theVector.PS;
4291 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
4293 TIDSortedElemSet copyElements;
4294 TIDSortedElemSet* workElements = &theElements;
4296 if ( myIsPreviewMode )
4298 TPreviewMesh * tmpMesh = getPreviewMesh();
4299 tmpMesh->Copy( theElements, copyElements);
4300 if ( !theCopy && !theTargetMesh )
4302 TIDSortedElemSet elemsAround, elemsAroundCopy;
4303 getElementsAround( theElements, getMeshDS(), elemsAround );
4304 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4306 workElements = & copyElements;
4307 theMakeGroups = false;
4310 ::SMESH_MeshEditor::PGroupIDs groupIds =
4311 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4313 if ( theCopy && !myIsPreviewMode )
4315 if ( theTargetMesh )
4317 theTargetMesh->GetMeshDS()->Modified();
4321 declareMeshModified( /*isReComputeSafe=*/false );
4325 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4327 SMESH_CATCH( SMESH::throwCorbaException );
4331 //=======================================================================
4332 //function : Translate
4334 //=======================================================================
4336 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
4337 const SMESH::DirStruct & theVector,
4338 CORBA::Boolean theCopy)
4339 throw (SALOME::SALOME_Exception)
4341 if (!myIsPreviewMode) {
4342 TPythonDump() << this << ".Translate( "
4343 << theIDsOfElements << ", "
4344 << theVector << ", "
4347 if (theIDsOfElements.length()) {
4348 TIDSortedElemSet elements;
4349 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4350 translate(elements, theVector, theCopy, false);
4354 //=======================================================================
4355 //function : TranslateObject
4357 //=======================================================================
4359 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
4360 const SMESH::DirStruct & theVector,
4361 CORBA::Boolean theCopy)
4362 throw (SALOME::SALOME_Exception)
4364 if (!myIsPreviewMode) {
4365 TPythonDump() << this << ".TranslateObject( "
4366 << theObject << ", "
4367 << theVector << ", "
4370 TIDSortedElemSet elements;
4372 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4374 prepareIdSource( theObject );
4375 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4376 translate(elements, theVector, theCopy, false);
4379 //=======================================================================
4380 //function : TranslateMakeGroups
4382 //=======================================================================
4384 SMESH::ListOfGroups*
4385 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
4386 const SMESH::DirStruct& theVector)
4387 throw (SALOME::SALOME_Exception)
4389 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4391 SMESH::ListOfGroups * aGroups = 0;
4392 if (theIDsOfElements.length()) {
4393 TIDSortedElemSet elements;
4394 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4395 aGroups = translate(elements,theVector,true,true);
4397 if (!myIsPreviewMode) {
4398 dumpGroupsList(aPythonDump, aGroups);
4399 aPythonDump << this << ".TranslateMakeGroups( "
4400 << theIDsOfElements << ", "
4401 << theVector << " )";
4406 //=======================================================================
4407 //function : TranslateObjectMakeGroups
4409 //=======================================================================
4411 SMESH::ListOfGroups*
4412 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4413 const SMESH::DirStruct& theVector)
4414 throw (SALOME::SALOME_Exception)
4416 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4418 SMESH::ListOfGroups * aGroups = 0;
4419 TIDSortedElemSet elements;
4420 prepareIdSource( theObject );
4421 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4422 aGroups = translate(elements, theVector, true, true);
4424 if (!myIsPreviewMode) {
4425 dumpGroupsList(aPythonDump, aGroups);
4426 aPythonDump << this << ".TranslateObjectMakeGroups( "
4427 << theObject << ", "
4428 << theVector << " )";
4433 //=======================================================================
4434 //function : TranslateMakeMesh
4436 //=======================================================================
4438 SMESH::SMESH_Mesh_ptr
4439 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
4440 const SMESH::DirStruct& theVector,
4441 CORBA::Boolean theCopyGroups,
4442 const char* theMeshName)
4443 throw (SALOME::SALOME_Exception)
4445 SMESH_Mesh_i* mesh_i;
4446 SMESH::SMESH_Mesh_var mesh;
4448 { // open new scope to dump "MakeMesh" command
4449 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4451 TPythonDump pydump; // to prevent dump at mesh creation
4453 mesh = makeMesh( theMeshName );
4454 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4456 if ( mesh_i && theIDsOfElements.length() )
4458 TIDSortedElemSet elements;
4459 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4460 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
4461 mesh_i->CreateGroupServants();
4464 if ( !myIsPreviewMode ) {
4465 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
4466 << theIDsOfElements << ", "
4467 << theVector << ", "
4468 << theCopyGroups << ", '"
4469 << theMeshName << "' )";
4474 if (!myIsPreviewMode && mesh_i)
4475 mesh_i->GetGroups();
4477 return mesh._retn();
4480 //=======================================================================
4481 //function : TranslateObjectMakeMesh
4483 //=======================================================================
4485 SMESH::SMESH_Mesh_ptr
4486 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4487 const SMESH::DirStruct& theVector,
4488 CORBA::Boolean theCopyGroups,
4489 const char* theMeshName)
4490 throw (SALOME::SALOME_Exception)
4493 SMESH_Mesh_i* mesh_i;
4494 SMESH::SMESH_Mesh_var mesh;
4495 { // open new scope to dump "MakeMesh" command
4496 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4498 TPythonDump pydump; // to prevent dump at mesh creation
4499 mesh = makeMesh( theMeshName );
4500 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4502 TIDSortedElemSet elements;
4503 prepareIdSource( theObject );
4505 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4507 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
4508 mesh_i->CreateGroupServants();
4510 if ( !myIsPreviewMode ) {
4511 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
4512 << theObject << ", "
4513 << theVector << ", "
4514 << theCopyGroups << ", '"
4515 << theMeshName << "' )";
4520 if (!myIsPreviewMode && mesh_i)
4521 mesh_i->GetGroups();
4523 return mesh._retn();
4525 SMESH_CATCH( SMESH::throwCorbaException );
4529 //=======================================================================
4532 //=======================================================================
4534 SMESH::ListOfGroups*
4535 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
4536 const SMESH::AxisStruct & theAxis,
4537 CORBA::Double theAngle,
4538 CORBA::Boolean theCopy,
4540 ::SMESH_Mesh* theTargetMesh)
4541 throw (SALOME::SALOME_Exception)
4546 if ( theTargetMesh )
4549 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
4550 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
4553 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
4555 TIDSortedElemSet copyElements;
4556 TIDSortedElemSet* workElements = &theElements;
4557 if ( myIsPreviewMode ) {
4558 TPreviewMesh * tmpMesh = getPreviewMesh();
4559 tmpMesh->Copy( theElements, copyElements );
4560 if ( !theCopy && !theTargetMesh )
4562 TIDSortedElemSet elemsAround, elemsAroundCopy;
4563 getElementsAround( theElements, getMeshDS(), elemsAround );
4564 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4566 workElements = ©Elements;
4567 theMakeGroups = false;
4570 ::SMESH_MeshEditor::PGroupIDs groupIds =
4571 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4573 if ( theCopy && !myIsPreviewMode)
4575 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4576 else declareMeshModified( /*isReComputeSafe=*/false );
4579 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4581 SMESH_CATCH( SMESH::throwCorbaException );
4585 //=======================================================================
4588 //=======================================================================
4590 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4591 const SMESH::AxisStruct & theAxis,
4592 CORBA::Double theAngle,
4593 CORBA::Boolean theCopy)
4594 throw (SALOME::SALOME_Exception)
4596 if (!myIsPreviewMode) {
4597 TPythonDump() << this << ".Rotate( "
4598 << theIDsOfElements << ", "
4600 << TVar( theAngle ) << ", "
4603 if (theIDsOfElements.length() > 0)
4605 TIDSortedElemSet elements;
4606 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4607 rotate(elements,theAxis,theAngle,theCopy,false);
4611 //=======================================================================
4612 //function : RotateObject
4614 //=======================================================================
4616 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4617 const SMESH::AxisStruct & theAxis,
4618 CORBA::Double theAngle,
4619 CORBA::Boolean theCopy)
4620 throw (SALOME::SALOME_Exception)
4622 if ( !myIsPreviewMode ) {
4623 TPythonDump() << this << ".RotateObject( "
4624 << theObject << ", "
4626 << TVar( theAngle ) << ", "
4629 TIDSortedElemSet elements;
4630 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4631 prepareIdSource( theObject );
4632 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4633 rotate(elements,theAxis,theAngle,theCopy,false);
4636 //=======================================================================
4637 //function : RotateMakeGroups
4639 //=======================================================================
4641 SMESH::ListOfGroups*
4642 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4643 const SMESH::AxisStruct& theAxis,
4644 CORBA::Double theAngle)
4645 throw (SALOME::SALOME_Exception)
4647 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4649 SMESH::ListOfGroups * aGroups = 0;
4650 if (theIDsOfElements.length() > 0)
4652 TIDSortedElemSet elements;
4653 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4654 aGroups = rotate(elements,theAxis,theAngle,true,true);
4656 if (!myIsPreviewMode) {
4657 dumpGroupsList(aPythonDump, aGroups);
4658 aPythonDump << this << ".RotateMakeGroups( "
4659 << theIDsOfElements << ", "
4661 << TVar( theAngle ) << " )";
4666 //=======================================================================
4667 //function : RotateObjectMakeGroups
4669 //=======================================================================
4671 SMESH::ListOfGroups*
4672 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4673 const SMESH::AxisStruct& theAxis,
4674 CORBA::Double theAngle)
4675 throw (SALOME::SALOME_Exception)
4677 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4679 SMESH::ListOfGroups * aGroups = 0;
4680 TIDSortedElemSet elements;
4681 prepareIdSource( theObject );
4682 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4683 aGroups = rotate(elements, theAxis, theAngle, true, true);
4685 if (!myIsPreviewMode) {
4686 dumpGroupsList(aPythonDump, aGroups);
4687 aPythonDump << this << ".RotateObjectMakeGroups( "
4688 << theObject << ", "
4690 << TVar( theAngle ) << " )";
4695 //=======================================================================
4696 //function : RotateMakeMesh
4698 //=======================================================================
4700 SMESH::SMESH_Mesh_ptr
4701 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4702 const SMESH::AxisStruct& theAxis,
4703 CORBA::Double theAngleInRadians,
4704 CORBA::Boolean theCopyGroups,
4705 const char* theMeshName)
4706 throw (SALOME::SALOME_Exception)
4709 SMESH::SMESH_Mesh_var mesh;
4710 SMESH_Mesh_i* mesh_i;
4712 { // open new scope to dump "MakeMesh" command
4713 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4715 TPythonDump pydump; // to prevent dump at mesh creation
4717 mesh = makeMesh( theMeshName );
4718 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4720 if ( mesh_i && theIDsOfElements.length() > 0 )
4722 TIDSortedElemSet elements;
4723 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4724 rotate(elements, theAxis, theAngleInRadians,
4725 false, theCopyGroups, & mesh_i->GetImpl());
4726 mesh_i->CreateGroupServants();
4728 if ( !myIsPreviewMode ) {
4729 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4730 << theIDsOfElements << ", "
4732 << TVar( theAngleInRadians ) << ", "
4733 << theCopyGroups << ", '"
4734 << theMeshName << "' )";
4739 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4740 mesh_i->GetGroups();
4742 return mesh._retn();
4744 SMESH_CATCH( SMESH::throwCorbaException );
4748 //=======================================================================
4749 //function : RotateObjectMakeMesh
4751 //=======================================================================
4753 SMESH::SMESH_Mesh_ptr
4754 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4755 const SMESH::AxisStruct& theAxis,
4756 CORBA::Double theAngleInRadians,
4757 CORBA::Boolean theCopyGroups,
4758 const char* theMeshName)
4759 throw (SALOME::SALOME_Exception)
4762 SMESH::SMESH_Mesh_var mesh;
4763 SMESH_Mesh_i* mesh_i;
4765 {// open new scope to dump "MakeMesh" command
4766 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4768 TPythonDump pydump; // to prevent dump at mesh creation
4769 mesh = makeMesh( theMeshName );
4770 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4772 TIDSortedElemSet elements;
4773 prepareIdSource( theObject );
4775 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4777 rotate(elements, theAxis, theAngleInRadians,
4778 false, theCopyGroups, & mesh_i->GetImpl());
4779 mesh_i->CreateGroupServants();
4781 if ( !myIsPreviewMode ) {
4782 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4783 << theObject << ", "
4785 << TVar( theAngleInRadians ) << ", "
4786 << theCopyGroups << ", '"
4787 << theMeshName << "' )";
4792 if (!myIsPreviewMode && mesh_i)
4793 mesh_i->GetGroups();
4795 return mesh._retn();
4797 SMESH_CATCH( SMESH::throwCorbaException );
4801 //=======================================================================
4804 //=======================================================================
4806 SMESH::ListOfGroups*
4807 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4808 const SMESH::PointStruct& thePoint,
4809 const SMESH::double_array& theScaleFact,
4810 CORBA::Boolean theCopy,
4812 ::SMESH_Mesh* theTargetMesh)
4813 throw (SALOME::SALOME_Exception)
4817 if ( theScaleFact.length() < 1 )
4818 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4819 if ( theScaleFact.length() == 2 )
4820 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4822 if ( theTargetMesh )
4825 TIDSortedElemSet elements;
4826 prepareIdSource( theObject );
4827 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4828 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4833 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4834 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4836 double tol = std::numeric_limits<double>::max();
4839 #if OCC_VERSION_LARGE > 0x06070100
4840 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4841 0, S[1], 0, thePoint.y * (1-S[1]),
4842 0, 0, S[2], thePoint.z * (1-S[2]) );
4844 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4845 0, S[1], 0, thePoint.y * (1-S[1]),
4846 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4849 TIDSortedElemSet copyElements;
4850 TIDSortedElemSet* workElements = &elements;
4851 if ( myIsPreviewMode )
4853 TPreviewMesh * tmpMesh = getPreviewMesh();
4854 tmpMesh->Copy( elements, copyElements);
4855 if ( !theCopy && !theTargetMesh )
4857 TIDSortedElemSet elemsAround, elemsAroundCopy;
4858 getElementsAround( elements, getMeshDS(), elemsAround );
4859 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4861 workElements = & copyElements;
4862 theMakeGroups = false;
4865 ::SMESH_MeshEditor::PGroupIDs groupIds =
4866 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4868 if ( theCopy && !myIsPreviewMode )
4870 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4871 else declareMeshModified( /*isReComputeSafe=*/false );
4873 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4875 SMESH_CATCH( SMESH::throwCorbaException );
4879 //=======================================================================
4882 //=======================================================================
4884 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4885 const SMESH::PointStruct& thePoint,
4886 const SMESH::double_array& theScaleFact,
4887 CORBA::Boolean theCopy)
4888 throw (SALOME::SALOME_Exception)
4890 if ( !myIsPreviewMode ) {
4891 TPythonDump() << this << ".Scale( "
4892 << theObject << ", "
4894 << TVar( theScaleFact ) << ", "
4897 scale(theObject, thePoint, theScaleFact, theCopy, false);
4901 //=======================================================================
4902 //function : ScaleMakeGroups
4904 //=======================================================================
4906 SMESH::ListOfGroups*
4907 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4908 const SMESH::PointStruct& thePoint,
4909 const SMESH::double_array& theScaleFact)
4910 throw (SALOME::SALOME_Exception)
4912 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4914 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4915 if (!myIsPreviewMode) {
4916 dumpGroupsList(aPythonDump, aGroups);
4917 aPythonDump << this << ".Scale("
4920 << TVar( theScaleFact ) << ",True,True)";
4926 //=======================================================================
4927 //function : ScaleMakeMesh
4929 //=======================================================================
4931 SMESH::SMESH_Mesh_ptr
4932 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4933 const SMESH::PointStruct& thePoint,
4934 const SMESH::double_array& theScaleFact,
4935 CORBA::Boolean theCopyGroups,
4936 const char* theMeshName)
4937 throw (SALOME::SALOME_Exception)
4939 SMESH_Mesh_i* mesh_i;
4940 SMESH::SMESH_Mesh_var mesh;
4941 { // open new scope to dump "MakeMesh" command
4942 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4944 TPythonDump pydump; // to prevent dump at mesh creation
4945 mesh = makeMesh( theMeshName );
4946 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4950 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4951 mesh_i->CreateGroupServants();
4953 if ( !myIsPreviewMode )
4954 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4955 << theObject << ", "
4957 << TVar( theScaleFact ) << ", "
4958 << theCopyGroups << ", '"
4959 << theMeshName << "' )";
4963 if (!myIsPreviewMode && mesh_i)
4964 mesh_i->GetGroups();
4966 return mesh._retn();
4970 //=======================================================================
4971 //function : FindCoincidentNodes
4973 //=======================================================================
4975 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4976 SMESH::array_of_long_array_out GroupsOfNodes)
4977 throw (SALOME::SALOME_Exception)
4982 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4983 TIDSortedNodeSet nodes; // no input nodes
4984 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4986 GroupsOfNodes = new SMESH::array_of_long_array;
4987 GroupsOfNodes->length( aListOfListOfNodes.size() );
4988 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4989 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4990 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4991 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4992 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4993 aGroup.length( aListOfNodes.size() );
4994 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4995 aGroup[ j ] = (*lIt)->GetID();
4997 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4998 << Tolerance << " )";
5000 SMESH_CATCH( SMESH::throwCorbaException );
5003 //=======================================================================
5004 //function : FindCoincidentNodesOnPart
5006 //=======================================================================
5008 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
5009 CORBA::Double Tolerance,
5010 SMESH::array_of_long_array_out GroupsOfNodes)
5011 throw (SALOME::SALOME_Exception)
5016 TIDSortedNodeSet nodes;
5017 prepareIdSource( theObject );
5018 idSourceToNodeSet( theObject, getMeshDS(), nodes );
5020 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
5022 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
5024 GroupsOfNodes = new SMESH::array_of_long_array;
5025 GroupsOfNodes->length( aListOfListOfNodes.size() );
5026 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
5027 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
5029 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
5030 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
5031 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
5032 aGroup.length( aListOfNodes.size() );
5033 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
5034 aGroup[ j ] = (*lIt)->GetID();
5036 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
5038 << Tolerance << " )";
5040 SMESH_CATCH( SMESH::throwCorbaException );
5043 //================================================================================
5045 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
5046 * ExceptSubMeshOrGroups
5048 //================================================================================
5050 void SMESH_MeshEditor_i::
5051 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
5052 CORBA::Double theTolerance,
5053 SMESH::array_of_long_array_out theGroupsOfNodes,
5054 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
5055 throw (SALOME::SALOME_Exception)
5060 TIDSortedNodeSet nodes;
5061 prepareIdSource( theObject );
5062 idSourceToNodeSet( theObject, getMeshDS(), nodes );
5064 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
5066 TIDSortedNodeSet exceptNodes;
5067 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
5068 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
5069 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
5070 nodes.erase( *avoidNode );
5072 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
5074 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
5076 theGroupsOfNodes = new SMESH::array_of_long_array;
5077 theGroupsOfNodes->length( aListOfListOfNodes.size() );
5078 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
5079 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
5081 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
5082 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
5083 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
5084 aGroup.length( aListOfNodes.size() );
5085 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
5086 aGroup[ j ] = (*lIt)->GetID();
5088 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
5090 << theTolerance << ", "
5091 << theExceptSubMeshOrGroups << " )";
5093 SMESH_CATCH( SMESH::throwCorbaException );
5096 //=======================================================================
5097 //function : MergeNodes
5099 //=======================================================================
5101 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
5102 throw (SALOME::SALOME_Exception)
5107 SMESHDS_Mesh* aMesh = getMeshDS();
5109 TPythonDump aTPythonDump;
5110 aTPythonDump << this << ".MergeNodes([";
5111 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
5112 for (int i = 0; i < GroupsOfNodes.length(); i++)
5114 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
5115 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
5116 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
5117 for ( int j = 0; j < aNodeGroup.length(); j++ )
5119 CORBA::Long index = aNodeGroup[ j ];
5120 const SMDS_MeshNode * node = aMesh->FindNode(index);
5122 aListOfNodes.push_back( node );
5124 if ( aListOfNodes.size() < 2 )
5125 aListOfListOfNodes.pop_back();
5127 if ( i > 0 ) aTPythonDump << ", ";
5128 aTPythonDump << aNodeGroup;
5130 getEditor().MergeNodes( aListOfListOfNodes );
5132 aTPythonDump << "])";
5134 declareMeshModified( /*isReComputeSafe=*/false );
5136 SMESH_CATCH( SMESH::throwCorbaException );
5139 //=======================================================================
5140 //function : FindEqualElements
5142 //=======================================================================
5144 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
5145 SMESH::array_of_long_array_out GroupsOfElementsID)
5146 throw (SALOME::SALOME_Exception)
5151 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
5152 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
5154 TIDSortedElemSet elems;
5155 prepareIdSource( theObject );
5156 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
5158 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
5159 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
5161 GroupsOfElementsID = new SMESH::array_of_long_array;
5162 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
5164 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
5165 aListOfListOfElementsID.begin();
5166 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
5168 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
5169 list<int>& listOfIDs = *arraysIt;
5170 aGroup.length( listOfIDs.size() );
5171 list<int>::iterator idIt = listOfIDs.begin();
5172 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
5173 aGroup[ k ] = *idIt;
5176 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
5180 SMESH_CATCH( SMESH::throwCorbaException );
5183 //=======================================================================
5184 //function : MergeElements
5186 //=======================================================================
5188 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
5189 throw (SALOME::SALOME_Exception)
5194 TPythonDump aTPythonDump;
5195 aTPythonDump << this << ".MergeElements( [";
5197 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
5199 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
5200 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
5201 aListOfListOfElementsID.push_back( list< int >() );
5202 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
5203 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
5204 CORBA::Long id = anElemsIDGroup[ j ];
5205 aListOfElemsID.push_back( id );
5207 if ( aListOfElemsID.size() < 2 )
5208 aListOfListOfElementsID.pop_back();
5209 if ( i > 0 ) aTPythonDump << ", ";
5210 aTPythonDump << anElemsIDGroup;
5213 getEditor().MergeElements(aListOfListOfElementsID);
5215 declareMeshModified( /*isReComputeSafe=*/true );
5217 aTPythonDump << "] )";
5219 SMESH_CATCH( SMESH::throwCorbaException );
5222 //=======================================================================
5223 //function : MergeEqualElements
5225 //=======================================================================
5227 void SMESH_MeshEditor_i::MergeEqualElements()
5228 throw (SALOME::SALOME_Exception)
5233 getEditor().MergeEqualElements();
5235 declareMeshModified( /*isReComputeSafe=*/true );
5237 TPythonDump() << this << ".MergeEqualElements()";
5239 SMESH_CATCH( SMESH::throwCorbaException );
5242 //=============================================================================
5244 * Move the node to a given point
5246 //=============================================================================
5248 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
5252 throw (SALOME::SALOME_Exception)
5255 initData(/*deleteSearchers=*/false);
5257 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
5261 if ( theNodeSearcher )
5262 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5264 if ( myIsPreviewMode ) // make preview data
5266 // in a preview mesh, make edges linked to a node
5267 TPreviewMesh& tmpMesh = *getPreviewMesh();
5268 TIDSortedElemSet linkedNodes;
5269 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5270 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5271 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
5272 for ( ; nIt != linkedNodes.end(); ++nIt )
5274 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
5275 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
5279 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
5280 // fill preview data
5282 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5283 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5285 getMeshDS()->MoveNode(node, x, y, z);
5287 if ( !myIsPreviewMode )
5289 // Update Python script
5290 TPythonDump() << "isDone = " << this << ".MoveNode( "
5291 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
5292 declareMeshModified( /*isReComputeSafe=*/false );
5295 SMESH_CATCH( SMESH::throwCorbaException );
5300 //================================================================================
5302 * \brief Return ID of node closest to a given point
5304 //================================================================================
5306 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
5309 throw (SALOME::SALOME_Exception)
5312 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5314 if ( !theNodeSearcher ) {
5315 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5318 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
5319 return node->GetID();
5321 SMESH_CATCH( SMESH::throwCorbaException );
5325 //================================================================================
5327 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
5328 * move the node closest to the point to point's location and return ID of the node
5330 //================================================================================
5332 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
5335 CORBA::Long theNodeID)
5336 throw (SALOME::SALOME_Exception)
5339 // We keep theNodeSearcher until any mesh modification:
5340 // 1) initData() deletes theNodeSearcher at any edition,
5341 // 2) TSearchersDeleter - at any mesh compute event and mesh change
5343 initData(/*deleteSearchers=*/false);
5345 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5347 int nodeID = theNodeID;
5348 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
5349 if ( !node ) // preview moving node
5351 if ( !theNodeSearcher ) {
5352 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5355 node = theNodeSearcher->FindClosestTo( p );
5358 nodeID = node->GetID();
5359 if ( myIsPreviewMode ) // make preview data
5361 // in a preview mesh, make edges linked to a node
5362 TPreviewMesh tmpMesh = *getPreviewMesh();
5363 TIDSortedElemSet linkedNodes;
5364 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5365 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5366 for ( ; nIt != linkedNodes.end(); ++nIt )
5368 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
5369 tmpMesh.Copy( &edge );
5372 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
5374 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
5375 // fill preview data
5377 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5379 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5383 getMeshDS()->MoveNode(node, x, y, z);
5387 if ( !myIsPreviewMode )
5389 TPythonDump() << "nodeID = " << this
5390 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
5391 << ", " << nodeID << " )";
5393 declareMeshModified( /*isReComputeSafe=*/false );
5398 SMESH_CATCH( SMESH::throwCorbaException );
5402 //=======================================================================
5404 * Return elements of given type where the given point is IN or ON.
5406 * 'ALL' type means elements of any type excluding nodes
5408 //=======================================================================
5410 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
5413 SMESH::ElementType type)
5414 throw (SALOME::SALOME_Exception)
5417 SMESH::long_array_var res = new SMESH::long_array;
5418 vector< const SMDS_MeshElement* > foundElems;
5420 theSearchersDeleter.Set( myMesh );
5421 if ( !theElementSearcher ) {
5422 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5424 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5425 SMDSAbs_ElementType( type ),
5427 res->length( foundElems.size() );
5428 for ( int i = 0; i < foundElems.size(); ++i )
5429 res[i] = foundElems[i]->GetID();
5433 SMESH_CATCH( SMESH::throwCorbaException );
5437 //=======================================================================
5438 //function : FindAmongElementsByPoint
5439 //purpose : Searching among the given elements, return elements of given type
5440 // where the given point is IN or ON.
5441 // 'ALL' type means elements of any type excluding nodes
5442 //=======================================================================
5445 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
5449 SMESH::ElementType type)
5450 throw (SALOME::SALOME_Exception)
5453 SMESH::long_array_var res = new SMESH::long_array;
5455 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
5456 if ( types->length() == 1 && // a part contains only nodes or 0D elements
5457 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
5458 type != types[0] ) // but search of elements of dim > 0
5461 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
5462 return FindElementsByPoint( x,y,z, type );
5464 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
5466 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
5467 if ( !theElementSearcher )
5469 // create a searcher from elementIDs
5470 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
5471 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
5473 if ( !idSourceToSet( elementIDs, meshDS, elements,
5474 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
5477 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5478 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
5480 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
5483 vector< const SMDS_MeshElement* > foundElems;
5485 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5486 SMDSAbs_ElementType( type ),
5488 res->length( foundElems.size() );
5489 for ( int i = 0; i < foundElems.size(); ++i )
5490 res[i] = foundElems[i]->GetID();
5494 SMESH_CATCH( SMESH::throwCorbaException );
5498 //=======================================================================
5499 //function : GetPointState
5500 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
5501 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
5502 //=======================================================================
5504 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
5507 throw (SALOME::SALOME_Exception)
5510 theSearchersDeleter.Set( myMesh );
5511 if ( !theElementSearcher ) {
5512 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5514 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
5516 SMESH_CATCH( SMESH::throwCorbaException );
5520 //=======================================================================
5521 //function : convError
5523 //=======================================================================
5525 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
5527 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
5531 RETCASE( SEW_BORDER1_NOT_FOUND );
5532 RETCASE( SEW_BORDER2_NOT_FOUND );
5533 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
5534 RETCASE( SEW_BAD_SIDE_NODES );
5535 RETCASE( SEW_VOLUMES_TO_SPLIT );
5536 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
5537 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
5538 RETCASE( SEW_BAD_SIDE1_NODES );
5539 RETCASE( SEW_BAD_SIDE2_NODES );
5541 return SMESH::SMESH_MeshEditor::SEW_OK;
5544 //=======================================================================
5545 //function : SewFreeBorders
5547 //=======================================================================
5549 SMESH::SMESH_MeshEditor::Sew_Error
5550 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
5551 CORBA::Long SecondNodeID1,
5552 CORBA::Long LastNodeID1,
5553 CORBA::Long FirstNodeID2,
5554 CORBA::Long SecondNodeID2,
5555 CORBA::Long LastNodeID2,
5556 CORBA::Boolean CreatePolygons,
5557 CORBA::Boolean CreatePolyedrs)
5558 throw (SALOME::SALOME_Exception)
5563 SMESHDS_Mesh* aMesh = getMeshDS();
5565 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5566 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5567 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5568 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5569 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5570 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
5572 if (!aBorderFirstNode ||
5573 !aBorderSecondNode||
5575 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5576 if (!aSide2FirstNode ||
5577 !aSide2SecondNode ||
5579 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5581 TPythonDump() << "error = " << this << ".SewFreeBorders( "
5582 << FirstNodeID1 << ", "
5583 << SecondNodeID1 << ", "
5584 << LastNodeID1 << ", "
5585 << FirstNodeID2 << ", "
5586 << SecondNodeID2 << ", "
5587 << LastNodeID2 << ", "
5588 << CreatePolygons<< ", "
5589 << CreatePolyedrs<< " )";
5591 SMESH::SMESH_MeshEditor::Sew_Error error =
5592 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5603 declareMeshModified( /*isReComputeSafe=*/false );
5606 SMESH_CATCH( SMESH::throwCorbaException );
5607 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5611 //=======================================================================
5612 //function : SewConformFreeBorders
5614 //=======================================================================
5616 SMESH::SMESH_MeshEditor::Sew_Error
5617 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
5618 CORBA::Long SecondNodeID1,
5619 CORBA::Long LastNodeID1,
5620 CORBA::Long FirstNodeID2,
5621 CORBA::Long SecondNodeID2)
5622 throw (SALOME::SALOME_Exception)
5627 SMESHDS_Mesh* aMesh = getMeshDS();
5629 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5630 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5631 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5632 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5633 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5634 const SMDS_MeshNode* aSide2ThirdNode = 0;
5636 if (!aBorderFirstNode ||
5637 !aBorderSecondNode||
5639 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5640 if (!aSide2FirstNode ||
5642 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5644 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
5645 << FirstNodeID1 << ", "
5646 << SecondNodeID1 << ", "
5647 << LastNodeID1 << ", "
5648 << FirstNodeID2 << ", "
5649 << SecondNodeID2 << " )";
5651 SMESH::SMESH_MeshEditor::Sew_Error error =
5652 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5661 declareMeshModified( /*isReComputeSafe=*/false );
5664 SMESH_CATCH( SMESH::throwCorbaException );
5665 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5669 //=======================================================================
5670 //function : SewBorderToSide
5672 //=======================================================================
5674 SMESH::SMESH_MeshEditor::Sew_Error
5675 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5676 CORBA::Long SecondNodeIDOnFreeBorder,
5677 CORBA::Long LastNodeIDOnFreeBorder,
5678 CORBA::Long FirstNodeIDOnSide,
5679 CORBA::Long LastNodeIDOnSide,
5680 CORBA::Boolean CreatePolygons,
5681 CORBA::Boolean CreatePolyedrs)
5682 throw (SALOME::SALOME_Exception)
5687 SMESHDS_Mesh* aMesh = getMeshDS();
5689 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5690 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5691 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5692 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5693 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5694 const SMDS_MeshNode* aSide2ThirdNode = 0;
5696 if (!aBorderFirstNode ||
5697 !aBorderSecondNode||
5699 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5700 if (!aSide2FirstNode ||
5702 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5704 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5705 << FirstNodeIDOnFreeBorder << ", "
5706 << SecondNodeIDOnFreeBorder << ", "
5707 << LastNodeIDOnFreeBorder << ", "
5708 << FirstNodeIDOnSide << ", "
5709 << LastNodeIDOnSide << ", "
5710 << CreatePolygons << ", "
5711 << CreatePolyedrs << ") ";
5713 SMESH::SMESH_MeshEditor::Sew_Error error =
5714 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5724 declareMeshModified( /*isReComputeSafe=*/false );
5727 SMESH_CATCH( SMESH::throwCorbaException );
5728 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5732 //=======================================================================
5733 //function : SewSideElements
5735 //=======================================================================
5737 SMESH::SMESH_MeshEditor::Sew_Error
5738 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5739 const SMESH::long_array& IDsOfSide2Elements,
5740 CORBA::Long NodeID1OfSide1ToMerge,
5741 CORBA::Long NodeID1OfSide2ToMerge,
5742 CORBA::Long NodeID2OfSide1ToMerge,
5743 CORBA::Long NodeID2OfSide2ToMerge)
5744 throw (SALOME::SALOME_Exception)
5749 SMESHDS_Mesh* aMesh = getMeshDS();
5751 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5752 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5753 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5754 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5756 if (!aFirstNode1ToMerge ||
5757 !aFirstNode2ToMerge )
5758 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5759 if (!aSecondNode1ToMerge||
5760 !aSecondNode2ToMerge)
5761 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5763 TIDSortedElemSet aSide1Elems, aSide2Elems;
5764 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5765 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5767 TPythonDump() << "error = " << this << ".SewSideElements( "
5768 << IDsOfSide1Elements << ", "
5769 << IDsOfSide2Elements << ", "
5770 << NodeID1OfSide1ToMerge << ", "
5771 << NodeID1OfSide2ToMerge << ", "
5772 << NodeID2OfSide1ToMerge << ", "
5773 << NodeID2OfSide2ToMerge << ")";
5775 SMESH::SMESH_MeshEditor::Sew_Error error =
5776 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5779 aSecondNode1ToMerge,
5780 aSecondNode2ToMerge));
5782 declareMeshModified( /*isReComputeSafe=*/false );
5785 SMESH_CATCH( SMESH::throwCorbaException );
5786 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5789 //================================================================================
5791 * \brief Set new nodes for given element
5792 * \param ide - element id
5793 * \param newIDs - new node ids
5794 * \retval CORBA::Boolean - true if result is OK
5796 //================================================================================
5798 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5799 const SMESH::long_array& newIDs)
5800 throw (SALOME::SALOME_Exception)
5805 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5806 if(!elem) return false;
5808 int nbn = newIDs.length();
5810 vector<const SMDS_MeshNode*> aNodes(nbn);
5813 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5816 aNodes[nbn1] = aNode;
5819 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5820 << ide << ", " << newIDs << " )";
5822 MESSAGE("ChangeElementNodes");
5823 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5825 declareMeshModified( /*isReComputeSafe=*/ !res );
5829 SMESH_CATCH( SMESH::throwCorbaException );
5833 //=======================================================================
5835 * \brief Makes a part of the mesh quadratic or bi-quadratic
5837 //=======================================================================
5839 void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d,
5840 CORBA::Boolean theToBiQuad,
5841 SMESH::SMESH_IDSource_ptr theObject)
5842 throw (SALOME::SALOME_Exception)
5845 TIDSortedElemSet elems;
5847 if ( !( elemsOK = CORBA::is_nil( theObject )))
5849 prepareIdSource( theObject );
5850 elemsOK = idSourceToSet( theObject, getMeshDS(), elems,
5851 SMDSAbs_All, /*emptyIfIsMesh=*/true );
5855 if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
5856 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5858 if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
5859 else getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
5861 declareMeshModified( /*isReComputeSafe=*/false );
5864 SMESH_CATCH( SMESH::throwCorbaException );
5867 //=======================================================================
5868 //function : ConvertFromQuadratic
5870 //=======================================================================
5872 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5873 throw (SALOME::SALOME_Exception)
5875 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5876 TPythonDump() << this << ".ConvertFromQuadratic()";
5877 declareMeshModified( /*isReComputeSafe=*/!isDone );
5881 //=======================================================================
5882 //function : ConvertToQuadratic
5884 //=======================================================================
5886 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5887 throw (SALOME::SALOME_Exception)
5889 convertToQuadratic( theForce3d, false );
5890 TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
5893 //================================================================================
5895 * \brief Makes a part of the mesh quadratic
5897 //================================================================================
5899 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5900 SMESH::SMESH_IDSource_ptr theObject)
5901 throw (SALOME::SALOME_Exception)
5903 convertToQuadratic( theForce3d, false, theObject );
5904 TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
5907 //================================================================================
5909 * \brief Makes a part of the mesh bi-quadratic
5911 //================================================================================
5913 void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean theForce3d,
5914 SMESH::SMESH_IDSource_ptr theObject)
5915 throw (SALOME::SALOME_Exception)
5917 convertToQuadratic( theForce3d, true, theObject );
5918 TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
5921 //================================================================================
5923 * \brief Makes a part of the mesh linear
5925 //================================================================================
5927 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5928 throw (SALOME::SALOME_Exception)
5934 TIDSortedElemSet elems;
5935 prepareIdSource( theObject );
5936 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5938 if ( elems.empty() )
5940 ConvertFromQuadratic();
5942 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5944 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5948 getEditor().ConvertFromQuadratic(elems);
5951 declareMeshModified( /*isReComputeSafe=*/false );
5953 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5955 SMESH_CATCH( SMESH::throwCorbaException );
5958 //=======================================================================
5959 //function : makeMesh
5960 //purpose : create a named imported mesh
5961 //=======================================================================
5963 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5965 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5966 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5967 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5968 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5969 gen->SetName( meshSO, theMeshName, "Mesh" );
5970 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5972 return mesh._retn();
5975 //=======================================================================
5976 //function : dumpGroupsList
5978 //=======================================================================
5980 void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPython,
5981 const SMESH::ListOfGroups * theGroupList)
5983 bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
5984 if ( isDumpGroupList )
5985 theDumpPython << theGroupList << " = ";
5988 //================================================================================
5990 \brief Generates the unique group name.
5991 \param thePrefix name prefix
5994 //================================================================================
5996 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5998 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5999 set<string> groupNames;
6001 // Get existing group names
6002 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
6003 SMESH::SMESH_GroupBase_var aGroup = groups[i];
6004 if (CORBA::is_nil(aGroup))
6007 CORBA::String_var name = aGroup->GetName();
6008 groupNames.insert( name.in() );
6012 string name = thePrefix;
6015 while (!groupNames.insert(name).second)
6016 name = SMESH_Comment( thePrefix ) << "_" << index++;
6021 //================================================================================
6023 * \brief Prepare SMESH_IDSource for work
6025 //================================================================================
6027 void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
6029 if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6031 SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
6032 filter->SetMesh( mesh );
6036 //================================================================================
6038 * \brief Duplicates given elements, i.e. creates new elements based on the
6039 * same nodes as the given ones.
6040 * \param theElements - container of elements to duplicate.
6041 * \param theGroupName - a name of group to contain the generated elements.
6042 * If a group with such a name already exists, the new elements
6043 * are added to the existng group, else a new group is created.
6044 * If \a theGroupName is empty, new elements are not added
6046 * \return a group where the new elements are added. NULL if theGroupName == "".
6049 //================================================================================
6051 SMESH::SMESH_Group_ptr
6052 SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
6053 const char* theGroupName)
6054 throw (SALOME::SALOME_Exception)
6056 SMESH::SMESH_Group_var newGroup;
6063 TIDSortedElemSet elems;
6064 prepareIdSource( theElements );
6065 if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
6067 getEditor().DoubleElements( elems );
6069 if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
6072 SMESH::ElementType type =
6073 SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
6074 // find existing group
6075 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
6076 for ( size_t i = 0; i < groups->length(); ++i )
6077 if ( groups[i]->GetType() == type )
6079 CORBA::String_var name = groups[i]->GetName();
6080 if ( strcmp( name, theGroupName ) == 0 ) {
6081 newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
6085 // create a new group
6086 if ( newGroup->_is_nil() )
6087 newGroup = myMesh_i->CreateGroup( type, theGroupName );
6089 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
6091 SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
6092 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
6093 for ( int i = 1; i <= aSeq.Length(); i++ )
6094 groupDS->SMDSGroup().Add( aSeq(i) );
6099 if ( !newGroup->_is_nil() )
6100 pyDump << newGroup << " = ";
6101 pyDump << this << ".DoubleElements( "
6102 << theElements << ", " << "'" << theGroupName <<"')";
6104 SMESH_CATCH( SMESH::throwCorbaException );
6106 return newGroup._retn();
6109 //================================================================================
6111 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6112 \param theNodes - identifiers of nodes to be doubled
6113 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
6114 nodes. If list of element identifiers is empty then nodes are doubled but
6115 they not assigned to elements
6116 \return TRUE if operation has been completed successfully, FALSE otherwise
6117 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
6119 //================================================================================
6121 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
6122 const SMESH::long_array& theModifiedElems )
6123 throw (SALOME::SALOME_Exception)
6128 list< int > aListOfNodes;
6130 for ( i = 0, n = theNodes.length(); i < n; i++ )
6131 aListOfNodes.push_back( theNodes[ i ] );
6133 list< int > aListOfElems;
6134 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
6135 aListOfElems.push_back( theModifiedElems[ i ] );
6137 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
6139 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6141 // Update Python script
6142 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
6146 SMESH_CATCH( SMESH::throwCorbaException );
6150 //================================================================================
6152 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6153 This method provided for convenience works as DoubleNodes() described above.
6154 \param theNodeId - identifier of node to be doubled.
6155 \param theModifiedElems - identifiers of elements to be updated.
6156 \return TRUE if operation has been completed successfully, FALSE otherwise
6157 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
6159 //================================================================================
6161 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
6162 const SMESH::long_array& theModifiedElems )
6163 throw (SALOME::SALOME_Exception)
6166 SMESH::long_array_var aNodes = new SMESH::long_array;
6167 aNodes->length( 1 );
6168 aNodes[ 0 ] = theNodeId;
6170 TPythonDump pyDump; // suppress dump by the next line
6172 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
6174 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
6178 SMESH_CATCH( SMESH::throwCorbaException );
6182 //================================================================================
6184 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6185 This method provided for convenience works as DoubleNodes() described above.
6186 \param theNodes - group of nodes to be doubled.
6187 \param theModifiedElems - group of elements to be updated.
6188 \return TRUE if operation has been completed successfully, FALSE otherwise
6189 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
6191 //================================================================================
6193 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
6194 SMESH::SMESH_GroupBase_ptr theModifiedElems )
6195 throw (SALOME::SALOME_Exception)
6198 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
6201 SMESH::long_array_var aNodes = theNodes->GetListOfID();
6202 SMESH::long_array_var aModifiedElems;
6203 if ( !CORBA::is_nil( theModifiedElems ) )
6204 aModifiedElems = theModifiedElems->GetListOfID();
6207 aModifiedElems = new SMESH::long_array;
6208 aModifiedElems->length( 0 );
6211 TPythonDump pyDump; // suppress dump by the next line
6213 bool done = DoubleNodes( aNodes, aModifiedElems );
6215 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
6219 SMESH_CATCH( SMESH::throwCorbaException );
6223 //================================================================================
6225 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6226 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
6227 * \param theNodes - group of nodes to be doubled.
6228 * \param theModifiedElems - group of elements to be updated.
6229 * \return a new group with newly created nodes
6230 * \sa DoubleNodeGroup()
6232 //================================================================================
6234 SMESH::SMESH_Group_ptr
6235 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
6236 SMESH::SMESH_GroupBase_ptr theModifiedElems )
6237 throw (SALOME::SALOME_Exception)
6240 SMESH::SMESH_Group_var aNewGroup;
6242 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
6243 return aNewGroup._retn();
6246 SMESH::long_array_var aNodes = theNodes->GetListOfID();
6247 SMESH::long_array_var aModifiedElems;
6248 if ( !CORBA::is_nil( theModifiedElems ) )
6249 aModifiedElems = theModifiedElems->GetListOfID();
6251 aModifiedElems = new SMESH::long_array;
6252 aModifiedElems->length( 0 );
6255 TPythonDump pyDump; // suppress dump by the next line
6257 bool aResult = DoubleNodes( aNodes, aModifiedElems );
6260 // Create group with newly created nodes
6261 SMESH::long_array_var anIds = GetLastCreatedNodes();
6262 if (anIds->length() > 0) {
6263 string anUnindexedName (theNodes->GetName());
6264 string aNewName = generateGroupName(anUnindexedName + "_double");
6265 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6266 aNewGroup->Add(anIds);
6267 pyDump << aNewGroup << " = ";
6271 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
6272 << theModifiedElems << " )";
6274 return aNewGroup._retn();
6276 SMESH_CATCH( SMESH::throwCorbaException );
6280 //================================================================================
6282 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6283 This method provided for convenience works as DoubleNodes() described above.
6284 \param theNodes - list of groups of nodes to be doubled
6285 \param theModifiedElems - list of groups of elements to be updated.
6286 \return TRUE if operation has been completed successfully, FALSE otherwise
6287 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
6289 //================================================================================
6291 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
6292 const SMESH::ListOfGroups& theModifiedElems )
6293 throw (SALOME::SALOME_Exception)
6298 std::list< int > aNodes;
6300 for ( i = 0, n = theNodes.length(); i < n; i++ )
6302 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
6303 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
6305 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6306 for ( j = 0, m = aCurr->length(); j < m; j++ )
6307 aNodes.push_back( aCurr[ j ] );
6311 std::list< int > anElems;
6312 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
6314 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
6315 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
6317 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6318 for ( j = 0, m = aCurr->length(); j < m; j++ )
6319 anElems.push_back( aCurr[ j ] );
6323 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
6325 declareMeshModified( /*isReComputeSafe=*/false );
6327 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
6331 SMESH_CATCH( SMESH::throwCorbaException );
6335 //================================================================================
6337 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6338 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
6339 * \param theNodes - group of nodes to be doubled.
6340 * \param theModifiedElems - group of elements to be updated.
6341 * \return a new group with newly created nodes
6342 * \sa DoubleNodeGroups()
6344 //================================================================================
6346 SMESH::SMESH_Group_ptr
6347 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
6348 const SMESH::ListOfGroups& theModifiedElems )
6349 throw (SALOME::SALOME_Exception)
6351 SMESH::SMESH_Group_var aNewGroup;
6353 TPythonDump pyDump; // suppress dump by the next line
6355 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
6359 // Create group with newly created nodes
6360 SMESH::long_array_var anIds = GetLastCreatedNodes();
6361 if (anIds->length() > 0) {
6362 string anUnindexedName (theNodes[0]->GetName());
6363 string aNewName = generateGroupName(anUnindexedName + "_double");
6364 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6365 aNewGroup->Add(anIds);
6366 pyDump << aNewGroup << " = ";
6370 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
6371 << theModifiedElems << " )";
6373 return aNewGroup._retn();
6377 //================================================================================
6379 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6380 \param theElems - the list of elements (edges or faces) to be replicated
6381 The nodes for duplication could be found from these elements
6382 \param theNodesNot - list of nodes to NOT replicate
6383 \param theAffectedElems - the list of elements (cells and edges) to which the
6384 replicated nodes should be associated to.
6385 \return TRUE if operation has been completed successfully, FALSE otherwise
6386 \sa DoubleNodeGroup(), DoubleNodeGroups()
6388 //================================================================================
6390 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
6391 const SMESH::long_array& theNodesNot,
6392 const SMESH::long_array& theAffectedElems )
6393 throw (SALOME::SALOME_Exception)
6398 SMESHDS_Mesh* aMeshDS = getMeshDS();
6399 TIDSortedElemSet anElems, aNodes, anAffected;
6400 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6401 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6402 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
6404 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6406 // Update Python script
6407 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
6408 << theNodesNot << ", " << theAffectedElems << " )";
6410 declareMeshModified( /*isReComputeSafe=*/false );
6413 SMESH_CATCH( SMESH::throwCorbaException );
6417 //================================================================================
6419 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6420 \param theElems - the list of elements (edges or faces) to be replicated
6421 The nodes for duplication could be found from these elements
6422 \param theNodesNot - list of nodes to NOT replicate
6423 \param theShape - shape to detect affected elements (element which geometric center
6424 located on or inside shape).
6425 The replicated nodes should be associated to affected elements.
6426 \return TRUE if operation has been completed successfully, FALSE otherwise
6427 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
6429 //================================================================================
6431 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
6432 const SMESH::long_array& theNodesNot,
6433 GEOM::GEOM_Object_ptr theShape )
6434 throw (SALOME::SALOME_Exception)
6440 SMESHDS_Mesh* aMeshDS = getMeshDS();
6441 TIDSortedElemSet anElems, aNodes;
6442 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6443 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6445 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6446 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6448 // Update Python script
6449 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
6450 << theNodesNot << ", " << theShape << " )";
6452 declareMeshModified( /*isReComputeSafe=*/false );
6455 SMESH_CATCH( SMESH::throwCorbaException );
6459 //================================================================================
6461 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6462 \param theElems - group of of elements (edges or faces) to be replicated
6463 \param theNodesNot - group of nodes not to replicated
6464 \param theAffectedElems - group of elements to which the replicated nodes
6465 should be associated to.
6466 \return TRUE if operation has been completed successfully, FALSE otherwise
6467 \sa DoubleNodes(), DoubleNodeGroups()
6469 //================================================================================
6472 SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
6473 SMESH::SMESH_GroupBase_ptr theNodesNot,
6474 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6475 throw (SALOME::SALOME_Exception)
6478 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6484 SMESHDS_Mesh* aMeshDS = getMeshDS();
6485 TIDSortedElemSet anElems, aNodes, anAffected;
6486 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6487 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6488 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6490 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6492 // Update Python script
6493 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
6494 << theNodesNot << ", " << theAffectedElems << " )";
6496 declareMeshModified( /*isReComputeSafe=*/false );
6499 SMESH_CATCH( SMESH::throwCorbaException );
6503 //================================================================================
6505 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6506 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6507 * \param theElems - group of of elements (edges or faces) to be replicated
6508 * \param theNodesNot - group of nodes not to replicated
6509 * \param theAffectedElems - group of elements to which the replicated nodes
6510 * should be associated to.
6511 * \return a new group with newly created elements
6512 * \sa DoubleNodeElemGroup()
6514 //================================================================================
6516 SMESH::SMESH_Group_ptr
6517 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
6518 SMESH::SMESH_GroupBase_ptr theNodesNot,
6519 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6520 throw (SALOME::SALOME_Exception)
6523 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
6527 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6528 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6530 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
6532 << theNodesNot << ", "
6533 << theAffectedElems << " )";
6535 return elemGroup._retn();
6538 //================================================================================
6540 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6541 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6542 * \param theElems - group of of elements (edges or faces) to be replicated
6543 * \param theNodesNot - group of nodes not to replicated
6544 * \param theAffectedElems - group of elements to which the replicated nodes
6545 * should be associated to.
6546 * \return a new group with newly created elements
6547 * \sa DoubleNodeElemGroup()
6549 //================================================================================
6551 SMESH::ListOfGroups*
6552 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
6553 SMESH::SMESH_GroupBase_ptr theNodesNot,
6554 SMESH::SMESH_GroupBase_ptr theAffectedElems,
6555 CORBA::Boolean theElemGroupNeeded,
6556 CORBA::Boolean theNodeGroupNeeded)
6557 throw (SALOME::SALOME_Exception)
6560 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6561 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6562 aTwoGroups->length( 2 );
6564 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6565 return aTwoGroups._retn();
6570 SMESHDS_Mesh* aMeshDS = getMeshDS();
6571 TIDSortedElemSet anElems, aNodes, anAffected;
6572 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6573 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6574 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6577 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6579 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6585 // Create group with newly created elements
6586 CORBA::String_var elemGroupName = theElems->GetName();
6587 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6588 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6590 SMESH::long_array_var anIds = GetLastCreatedElems();
6591 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6592 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6593 aNewElemGroup->Add(anIds);
6595 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6597 SMESH::long_array_var anIds = GetLastCreatedNodes();
6598 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6599 aNewNodeGroup->Add(anIds);
6603 // Update Python script
6606 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6607 else pyDump << aNewElemGroup << ", ";
6608 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6609 else pyDump << aNewNodeGroup << " ] = ";
6611 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
6612 << theNodesNot << ", "
6613 << theAffectedElems << ", "
6614 << theElemGroupNeeded << ", "
6615 << theNodeGroupNeeded <<" )";
6617 aTwoGroups[0] = aNewElemGroup._retn();
6618 aTwoGroups[1] = aNewNodeGroup._retn();
6619 return aTwoGroups._retn();
6621 SMESH_CATCH( SMESH::throwCorbaException );
6625 //================================================================================
6627 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6628 \param theElems - group of of elements (edges or faces) to be replicated
6629 \param theNodesNot - group of nodes not to replicated
6630 \param theShape - shape to detect affected elements (element which geometric center
6631 located on or inside shape).
6632 The replicated nodes should be associated to affected elements.
6633 \return TRUE if operation has been completed successfully, FALSE otherwise
6634 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
6636 //================================================================================
6639 SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
6640 SMESH::SMESH_GroupBase_ptr theNodesNot,
6641 GEOM::GEOM_Object_ptr theShape )
6642 throw (SALOME::SALOME_Exception)
6645 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6651 SMESHDS_Mesh* aMeshDS = getMeshDS();
6652 TIDSortedElemSet anElems, aNodes, anAffected;
6653 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6654 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6656 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6657 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6660 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6662 // Update Python script
6663 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
6664 << theNodesNot << ", " << theShape << " )";
6667 SMESH_CATCH( SMESH::throwCorbaException );
6671 //================================================================================
6673 * \brief Re-load elements from a list of groups into a TIDSortedElemSet
6674 * \param [in] theGrpList - groups
6675 * \param [in] theMeshDS - mesh
6676 * \param [out] theElemSet - set of elements
6677 * \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
6679 //================================================================================
6681 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
6682 SMESHDS_Mesh* theMeshDS,
6683 TIDSortedElemSet& theElemSet,
6684 const bool theIsNodeGrp)
6686 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
6688 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
6689 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
6690 : aGrp->GetType() != SMESH::NODE ) )
6692 SMESH::long_array_var anIDs = aGrp->GetIDs();
6693 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
6698 //================================================================================
6700 \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6701 This method provided for convenience works as DoubleNodes() described above.
6702 \param theElems - list of groups of elements (edges or faces) to be replicated
6703 \param theNodesNot - list of groups of nodes not to replicated
6704 \param theAffectedElems - group of elements to which the replicated nodes
6705 should be associated to.
6706 \return TRUE if operation has been completed successfully, FALSE otherwise
6707 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
6709 //================================================================================
6712 SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
6713 const SMESH::ListOfGroups& theNodesNot,
6714 const SMESH::ListOfGroups& theAffectedElems)
6715 throw (SALOME::SALOME_Exception)
6721 SMESHDS_Mesh* aMeshDS = getMeshDS();
6722 TIDSortedElemSet anElems, aNodes, anAffected;
6723 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6724 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6725 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6727 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6729 // Update Python script
6730 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
6731 << &theNodesNot << ", " << &theAffectedElems << " )";
6733 declareMeshModified( /*isReComputeSafe=*/false );
6736 SMESH_CATCH( SMESH::throwCorbaException );
6740 //================================================================================
6742 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6743 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6744 \param theElems - list of groups of elements (edges or faces) to be replicated
6745 \param theNodesNot - list of groups of nodes not to replicated
6746 \param theAffectedElems - group of elements to which the replicated nodes
6747 should be associated to.
6748 * \return a new group with newly created elements
6749 * \sa DoubleNodeElemGroups()
6751 //================================================================================
6753 SMESH::SMESH_Group_ptr
6754 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
6755 const SMESH::ListOfGroups& theNodesNot,
6756 const SMESH::ListOfGroups& theAffectedElems)
6757 throw (SALOME::SALOME_Exception)
6760 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
6764 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6765 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6767 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
6769 << theNodesNot << ", "
6770 << theAffectedElems << " )";
6772 return elemGroup._retn();
6775 //================================================================================
6777 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6778 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6779 \param theElems - list of groups of elements (edges or faces) to be replicated
6780 \param theNodesNot - list of groups of nodes not to replicated
6781 \param theAffectedElems - group of elements to which the replicated nodes
6782 should be associated to.
6783 * \return a new group with newly created elements
6784 * \sa DoubleNodeElemGroups()
6786 //================================================================================
6788 SMESH::ListOfGroups*
6789 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
6790 const SMESH::ListOfGroups& theNodesNot,
6791 const SMESH::ListOfGroups& theAffectedElems,
6792 CORBA::Boolean theElemGroupNeeded,
6793 CORBA::Boolean theNodeGroupNeeded)
6794 throw (SALOME::SALOME_Exception)
6797 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6798 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6799 aTwoGroups->length( 2 );
6804 SMESHDS_Mesh* aMeshDS = getMeshDS();
6805 TIDSortedElemSet anElems, aNodes, anAffected;
6806 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6807 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6808 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6810 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6812 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6817 // Create group with newly created elements
6818 CORBA::String_var elemGroupName = theElems[0]->GetName();
6819 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6820 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6822 SMESH::long_array_var anIds = GetLastCreatedElems();
6823 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6824 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6825 aNewElemGroup->Add(anIds);
6827 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6829 SMESH::long_array_var anIds = GetLastCreatedNodes();
6830 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6831 aNewNodeGroup->Add(anIds);
6835 // Update Python script
6838 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6839 else pyDump << aNewElemGroup << ", ";
6840 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6841 else pyDump << aNewNodeGroup << " ] = ";
6843 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6844 << &theNodesNot << ", "
6845 << &theAffectedElems << ", "
6846 << theElemGroupNeeded << ", "
6847 << theNodeGroupNeeded << " )";
6849 aTwoGroups[0] = aNewElemGroup._retn();
6850 aTwoGroups[1] = aNewNodeGroup._retn();
6851 return aTwoGroups._retn();
6853 SMESH_CATCH( SMESH::throwCorbaException );
6857 //================================================================================
6859 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6860 This method provided for convenience works as DoubleNodes() described above.
6861 \param theElems - list of groups of elements (edges or faces) to be replicated
6862 \param theNodesNot - list of groups of nodes not to replicated
6863 \param theShape - shape to detect affected elements (element which geometric center
6864 located on or inside shape).
6865 The replicated nodes should be associated to affected elements.
6866 \return TRUE if operation has been completed successfully, FALSE otherwise
6867 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6869 //================================================================================
6872 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6873 const SMESH::ListOfGroups& theNodesNot,
6874 GEOM::GEOM_Object_ptr theShape )
6875 throw (SALOME::SALOME_Exception)
6881 SMESHDS_Mesh* aMeshDS = getMeshDS();
6882 TIDSortedElemSet anElems, aNodes;
6883 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6884 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6886 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6887 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6889 // Update Python script
6890 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6891 << &theNodesNot << ", " << theShape << " )";
6893 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6896 SMESH_CATCH( SMESH::throwCorbaException );
6900 //================================================================================
6902 \brief Identify the elements that will be affected by node duplication (actual
6903 duplication is not performed.
6904 This method is the first step of DoubleNodeElemGroupsInRegion.
6905 \param theElems - list of groups of elements (edges or faces) to be replicated
6906 \param theNodesNot - list of groups of nodes not to replicated
6907 \param theShape - shape to detect affected elements (element which geometric center
6908 located on or inside shape).
6909 The replicated nodes should be associated to affected elements.
6910 \return groups of affected elements
6911 \sa DoubleNodeElemGroupsInRegion()
6913 //================================================================================
6914 SMESH::ListOfGroups*
6915 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6916 const SMESH::ListOfGroups& theNodesNot,
6917 GEOM::GEOM_Object_ptr theShape )
6918 throw (SALOME::SALOME_Exception)
6921 MESSAGE("AffectedElemGroupsInRegion");
6922 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6923 bool isEdgeGroup = false;
6924 bool isFaceGroup = false;
6925 bool isVolumeGroup = false;
6926 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6927 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6928 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6932 ::SMESH_MeshEditor aMeshEditor(myMesh);
6934 SMESHDS_Mesh* aMeshDS = getMeshDS();
6935 TIDSortedElemSet anElems, aNodes;
6936 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6937 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6939 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6940 TIDSortedElemSet anAffected;
6941 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6944 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6949 int lg = anAffected.size();
6950 MESSAGE("lg="<< lg);
6951 SMESH::long_array_var volumeIds = new SMESH::long_array;
6952 volumeIds->length(lg);
6953 SMESH::long_array_var faceIds = new SMESH::long_array;
6954 faceIds->length(lg);
6955 SMESH::long_array_var edgeIds = new SMESH::long_array;
6956 edgeIds->length(lg);
6961 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6962 for (; eIt != anAffected.end(); ++eIt)
6964 const SMDS_MeshElement* anElem = *eIt;
6967 int elemId = anElem->GetID();
6968 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6969 volumeIds[ivol++] = elemId;
6970 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6971 faceIds[iface++] = elemId;
6972 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6973 edgeIds[iedge++] = elemId;
6975 volumeIds->length(ivol);
6976 faceIds->length(iface);
6977 edgeIds->length(iedge);
6979 aNewVolumeGroup->Add(volumeIds);
6980 aNewFaceGroup->Add(faceIds);
6981 aNewEdgeGroup->Add(edgeIds);
6982 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6983 isFaceGroup = (aNewFaceGroup->Size() > 0);
6984 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6988 if (isEdgeGroup) nbGroups++;
6989 if (isFaceGroup) nbGroups++;
6990 if (isVolumeGroup) nbGroups++;
6991 aListOfGroups->length(nbGroups);
6994 if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
6995 if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
6996 if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
6998 // Update Python script
7001 if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
7002 if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
7003 if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
7005 pyDump << this << ".AffectedElemGroupsInRegion( "
7006 << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
7008 return aListOfGroups._retn();
7010 SMESH_CATCH( SMESH::throwCorbaException );
7014 //================================================================================
7016 \brief Generated skin mesh (containing 2D cells) from 3D mesh
7017 The created 2D mesh elements based on nodes of free faces of boundary volumes
7018 \return TRUE if operation has been completed successfully, FALSE otherwise
7020 //================================================================================
7022 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
7023 throw (SALOME::SALOME_Exception)
7028 bool aResult = getEditor().Make2DMeshFrom3D();
7030 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
7032 declareMeshModified( /*isReComputeSafe=*/ !aResult );
7035 SMESH_CATCH( SMESH::throwCorbaException );
7039 //================================================================================
7041 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
7042 * The list of groups must contain at least two groups. The groups have to be disjoint:
7043 * no common element into two different groups.
7044 * The nodes of the internal faces at the boundaries of the groups are doubled.
7045 * Optionally, the internal faces are replaced by flat elements.
7046 * Triangles are transformed into prisms, and quadrangles into hexahedrons.
7047 * The flat elements are stored in groups of volumes.
7048 * These groups are named according to the position of the group in the list:
7049 * 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.
7050 * 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.
7051 * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
7052 * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
7053 * \param theDomains - list of groups of volumes
7054 * \param createJointElems - if TRUE, create the elements
7055 * \param onAllBoundaries - if TRUE, the nodes and elements are also created on
7056 * the boundary between \a theDomains and the rest mesh
7057 * \return TRUE if operation has been completed successfully, FALSE otherwise
7059 //================================================================================
7062 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
7063 CORBA::Boolean createJointElems,
7064 CORBA::Boolean onAllBoundaries )
7065 throw (SALOME::SALOME_Exception)
7072 SMESHDS_Mesh* aMeshDS = getMeshDS();
7074 // MESSAGE("theDomains.length = "<<theDomains.length());
7075 if ( theDomains.length() <= 1 && !onAllBoundaries )
7076 THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
7078 vector<TIDSortedElemSet> domains;
7079 domains.resize( theDomains.length() );
7081 for ( int i = 0, n = theDomains.length(); i < n; i++ )
7083 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
7084 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
7086 // if ( aGrp->GetType() != SMESH::VOLUME )
7087 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
7088 SMESH::long_array_var anIDs = aGrp->GetIDs();
7089 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
7093 isOK = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems, onAllBoundaries );
7094 // TODO publish the groups of flat elements in study
7096 declareMeshModified( /*isReComputeSafe=*/ !isOK );
7098 // Update Python script
7099 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
7100 << ", " << createJointElems << ", " << onAllBoundaries << " )";
7102 SMESH_CATCH( SMESH::throwCorbaException );
7104 myMesh_i->CreateGroupServants(); // publish created groups if any
7109 //================================================================================
7111 * \brief Double nodes on some external faces and create flat elements.
7112 * Flat elements are mainly used by some types of mechanic calculations.
7114 * Each group of the list must be constituted of faces.
7115 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
7116 * @param theGroupsOfFaces - list of groups of faces
7117 * @return TRUE if operation has been completed successfully, FALSE otherwise
7119 //================================================================================
7122 SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
7123 throw (SALOME::SALOME_Exception)
7128 SMESHDS_Mesh* aMeshDS = getMeshDS();
7130 vector<TIDSortedElemSet> faceGroups;
7133 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
7135 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
7136 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
7138 TIDSortedElemSet faceGroup;
7140 faceGroups.push_back(faceGroup);
7141 SMESH::long_array_var anIDs = aGrp->GetIDs();
7142 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
7146 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
7147 // TODO publish the groups of flat elements in study
7149 declareMeshModified( /*isReComputeSafe=*/ !aResult );
7151 // Update Python script
7152 TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
7155 SMESH_CATCH( SMESH::throwCorbaException );
7159 //================================================================================
7161 * \brief Identify all the elements around a geom shape, get the faces delimiting
7164 * Build groups of volume to remove, groups of faces to replace on the skin of the
7165 * object, groups of faces to remove inside the object, (idem edges).
7166 * Build ordered list of nodes at the border of each group of faces to replace
7167 * (to be used to build a geom subshape).
7169 //================================================================================
7171 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
7172 GEOM::GEOM_Object_ptr theShape,
7173 const char* groupName,
7174 const SMESH::double_array& theNodesCoords,
7175 SMESH::array_of_long_array_out GroupsOfNodes)
7176 throw (SALOME::SALOME_Exception)
7181 std::vector<std::vector<int> > aListOfListOfNodes;
7182 ::SMESH_MeshEditor aMeshEditor( myMesh );
7184 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
7185 if ( !theNodeSearcher )
7186 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
7188 vector<double> nodesCoords;
7189 for (int i = 0; i < theNodesCoords.length(); i++)
7191 nodesCoords.push_back( theNodesCoords[i] );
7194 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
7195 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
7196 nodesCoords, aListOfListOfNodes);
7198 GroupsOfNodes = new SMESH::array_of_long_array;
7199 GroupsOfNodes->length( aListOfListOfNodes.size() );
7200 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
7201 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
7203 vector<int>& aListOfNodes = *llIt;
7204 vector<int>::iterator lIt = aListOfNodes.begin();;
7205 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
7206 aGroup.length( aListOfNodes.size() );
7207 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
7208 aGroup[ j ] = (*lIt);
7210 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
7213 << ", '" << groupName << "', "
7214 << theNodesCoords << " )";
7216 SMESH_CATCH( SMESH::throwCorbaException );
7219 // issue 20749 ===================================================================
7221 * \brief Creates missing boundary elements
7222 * \param elements - elements whose boundary is to be checked
7223 * \param dimension - defines type of boundary elements to create
7224 * \param groupName - a name of group to store created boundary elements in,
7225 * "" means not to create the group
7226 * \param meshName - a name of new mesh to store created boundary elements in,
7227 * "" means not to create the new mesh
7228 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
7229 * \param toCopyExistingBondary - if true, not only new but also pre-existing
7230 * boundary elements will be copied into the new mesh
7231 * \param group - returns the create group, if any
7232 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
7234 // ================================================================================
7236 SMESH::SMESH_Mesh_ptr
7237 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
7238 SMESH::Bnd_Dimension dim,
7239 const char* groupName,
7240 const char* meshName,
7241 CORBA::Boolean toCopyElements,
7242 CORBA::Boolean toCopyExistingBondary,
7243 SMESH::SMESH_Group_out group)
7244 throw (SALOME::SALOME_Exception)
7249 if ( dim > SMESH::BND_1DFROM2D )
7250 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7252 SMESHDS_Mesh* aMeshDS = getMeshDS();
7254 SMESH::SMESH_Mesh_var mesh_var;
7255 SMESH::SMESH_Group_var group_var;
7259 TIDSortedElemSet elements;
7260 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
7261 prepareIdSource( idSource );
7262 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
7266 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
7267 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7269 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
7271 // group of new boundary elements
7272 SMESH_Group* smesh_group = 0;
7273 if ( strlen(groupName) )
7275 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
7276 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7277 smesh_group = group_i->GetSmeshGroup();
7281 getEditor().MakeBoundaryMesh( elements,
7282 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7286 toCopyExistingBondary);
7289 smesh_mesh->GetMeshDS()->Modified();
7292 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7294 // result of MakeBoundaryMesh() is a tuple (mesh, group)
7295 if ( mesh_var->_is_nil() )
7296 pyDump << myMesh_i->_this() << ", ";
7298 pyDump << mesh_var << ", ";
7299 if ( group_var->_is_nil() )
7300 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7302 pyDump << group_var << " = ";
7303 pyDump << this << ".MakeBoundaryMesh( "
7305 << "SMESH." << dimName[int(dim)] << ", "
7306 << "'" << groupName << "', "
7307 << "'" << meshName<< "', "
7308 << toCopyElements << ", "
7309 << toCopyExistingBondary << ")";
7311 group = group_var._retn();
7312 return mesh_var._retn();
7314 SMESH_CATCH( SMESH::throwCorbaException );
7315 return SMESH::SMESH_Mesh::_nil();
7318 //================================================================================
7320 * \brief Creates missing boundary elements
7321 * \param dimension - defines type of boundary elements to create
7322 * \param groupName - a name of group to store all boundary elements in,
7323 * "" means not to create the group
7324 * \param meshName - a name of a new mesh, which is a copy of the initial
7325 * mesh + created boundary elements; "" means not to create the new mesh
7326 * \param toCopyAll - if true, the whole initial mesh will be copied into
7327 * the new mesh else only boundary elements will be copied into the new mesh
7328 * \param groups - optional groups of elements to make boundary around
7329 * \param mesh - returns the mesh where elements were added to
7330 * \param group - returns the created group, if any
7331 * \retval long - number of added boundary elements
7333 //================================================================================
7335 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
7336 const char* groupName,
7337 const char* meshName,
7338 CORBA::Boolean toCopyAll,
7339 const SMESH::ListOfIDSources& groups,
7340 SMESH::SMESH_Mesh_out mesh,
7341 SMESH::SMESH_Group_out group)
7342 throw (SALOME::SALOME_Exception)
7347 if ( dim > SMESH::BND_1DFROM2D )
7348 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7350 // separate groups belonging to this and other mesh
7351 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
7352 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
7353 groupsOfThisMesh->length( groups.length() );
7354 groupsOfOtherMesh->length( groups.length() );
7355 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
7356 for ( int i = 0; i < groups.length(); ++i )
7358 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
7359 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
7360 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
7362 groupsOfThisMesh[ nbGroups++ ] = groups[i];
7363 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
7364 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
7366 groupsOfThisMesh->length( nbGroups );
7367 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
7372 if ( nbGroupsOfOtherMesh > 0 )
7374 // process groups belonging to another mesh
7375 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
7376 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
7377 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
7378 groupsOfOtherMesh, mesh, group );
7381 SMESH::SMESH_Mesh_var mesh_var;
7382 SMESH::SMESH_Group_var group_var;
7385 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
7386 const bool toCopyMesh = ( strlen( meshName ) > 0 );
7390 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
7392 /*toCopyGroups=*/false,
7393 /*toKeepIDs=*/true);
7395 mesh_var = makeMesh(meshName);
7397 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7398 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
7401 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
7402 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
7404 // group of boundary elements
7405 SMESH_Group* smesh_group = 0;
7406 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
7407 if ( strlen(groupName) )
7409 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
7410 group_var = mesh_i->CreateGroup( groupType, groupName );
7411 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7412 smesh_group = group_i->GetSmeshGroup();
7415 TIDSortedElemSet elements;
7417 if ( groups.length() > 0 )
7419 for ( int i = 0; i < nbGroups; ++i )
7422 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
7424 SMESH::Bnd_Dimension bdim =
7425 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
7426 nbAdded += getEditor().MakeBoundaryMesh( elements,
7427 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
7430 /*toCopyElements=*/false,
7431 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7432 /*toAddExistingBondary=*/true,
7433 /*aroundElements=*/true);
7439 nbAdded += getEditor().MakeBoundaryMesh( elements,
7440 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7443 /*toCopyElements=*/false,
7444 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7445 /*toAddExistingBondary=*/true);
7447 tgtMesh->GetMeshDS()->Modified();
7449 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7451 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
7452 pyDump << "nbAdded, ";
7453 if ( mesh_var->_is_nil() )
7454 pyDump << myMesh_i->_this() << ", ";
7456 pyDump << mesh_var << ", ";
7457 if ( group_var->_is_nil() )
7458 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7460 pyDump << group_var << " = ";
7461 pyDump << this << ".MakeBoundaryElements( "
7462 << "SMESH." << dimName[int(dim)] << ", "
7463 << "'" << groupName << "', "
7464 << "'" << meshName<< "', "
7465 << toCopyAll << ", "
7468 mesh = mesh_var._retn();
7469 group = group_var._retn();
7472 SMESH_CATCH( SMESH::throwCorbaException );